diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..7a977433 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 +updates: +- package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + groups: + python: + patterns: + - "*" +- package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "weekly" + groups: + rust: + patterns: + - "*" diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c0c21bd0..d4602fbe 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -2,7 +2,7 @@ name: linux on: push: - branches: [main] + branches: [ main ] pull_request: concurrency: @@ -13,11 +13,14 @@ env: FORCE_COLOR: 1 jobs: - pythonbuild: - if: ${{ needs.generate-matrix.outputs.pythonbuild_changed == 'true' || needs.generate-matrix.outputs.any_builds == 'true' || github.ref == 'refs/heads/main' }} + crate-build: needs: - generate-matrix - runs-on: depot-ubuntu-22.04 + runs-on: ${{ matrix.runner }} + strategy: + matrix: ${{ fromJson(needs.generate-matrix.outputs.crate-build-matrix) }} + fail-fast: false + name: crate / ${{ matrix.arch }} steps: - name: Install System Dependencies run: | @@ -45,7 +48,7 @@ jobs: - name: Upload pythonbuild Executable uses: actions/upload-artifact@v4 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: target/release/pythonbuild image: @@ -54,17 +57,9 @@ jobs: - generate-matrix strategy: fail-fast: false - matrix: - image: - - build - - build.cross - - build.cross-riscv64 - - gcc - - xcb - - xcb.cross - - xcb.cross-riscv64 - name: ${{ matrix.image }} - runs-on: depot-ubuntu-22.04 + matrix: ${{ fromJson(needs.generate-matrix.outputs.docker-build-matrix) }} + name: image / ${{ matrix.arch }} / ${{ matrix.name }} + runs-on: ${{ matrix.runner }} permissions: packages: write steps: @@ -98,39 +93,40 @@ jobs: uses: docker/build-push-action@v5 with: context: . - file: build/${{ matrix.image }}.Dockerfile + file: build/${{ matrix.name }}.Dockerfile labels: org.opencontainers.image.source=https://github.com/${{ env.REPO_NAME }} # Cache from/to the current branch of the current repo as the primary cache key. # Cache from the default branch of the current repo so branches can have cache hits. # Cache from the default branch of the canonical repo so forks can have cache hits. # Ignore errors on cache writes so CI of forks works without a valid GHCR config. cache-from: | - type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-${{ env.GIT_REF_NAME }} - type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-main - type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.image }}-main + type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-${{ env.GIT_REF_NAME }} + type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-main + type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.name }}-linux_${{ matrix.arch }}-main cache-to: | - type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-${{ env.GIT_REF_NAME }},ignore-error=true + type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-${{ env.GIT_REF_NAME }},ignore-error=true outputs: | - type=docker,dest=build/image-${{ matrix.image }}.tar + type=docker,dest=build/image-${{ matrix.name }}.linux_${{ matrix.arch }}.tar - name: Compress Image run: | - echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.image }} + echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.name }}.linux_${{ matrix.arch }} zstd -v -T0 -6 --rm build/image-*.tar - name: Upload Docker Image uses: actions/upload-artifact@v4 with: - name: image-${{ matrix.image }} + name: image-${{ matrix.name }}-linux_${{ matrix.arch }} path: build/image-* generate-matrix: runs-on: ubuntu-latest outputs: - matrix-0: ${{ steps.set-matrix.outputs.matrix-0 }} - matrix-1: ${{ steps.set-matrix.outputs.matrix-1 }} + python-build-matrix-0: ${{ steps.set-matrix.outputs.python-build-matrix-0 }} + python-build-matrix-1: ${{ steps.set-matrix.outputs.python-build-matrix-1 }} + docker-build-matrix: ${{ steps.set-matrix.outputs.docker-build-matrix }} + crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }} any_builds: ${{ steps.set-matrix.outputs.any_builds }} - pythonbuild_changed: ${{ steps.check-pythonbuild.outputs.changed }} steps: - uses: actions/checkout@v4 with: @@ -146,6 +142,18 @@ jobs: LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")') echo "labels=$LABELS" >> $GITHUB_OUTPUT + - name: Check if the `pythonbuild` crate changed + id: check-pythonbuild + env: + BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} + run: | + merge_base=$(git merge-base HEAD "origin/${BASE_REF}") + if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + - name: Generate build matrix id: set-matrix run: | @@ -153,15 +161,18 @@ jobs: --platform linux \ --labels '${{ steps.get-labels.outputs.labels }}' \ --max-shards 2 \ + ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} \ > matrix.json - echo "matrix-0=$(jq -c '.["0"]' matrix.json)" >> $GITHUB_OUTPUT - echo "matrix-1=$(jq -c '.["1"]' matrix.json)" >> $GITHUB_OUTPUT + echo "python-build-matrix-0=$(jq -c '."python-build"["0"]' matrix.json)" >> $GITHUB_OUTPUT + echo "python-build-matrix-1=$(jq -c '."python-build"["1"]' matrix.json)" >> $GITHUB_OUTPUT + echo "docker-build-matrix=$(jq -c '."docker-build"' matrix.json)" >> $GITHUB_OUTPUT + echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT # Display the matrix for debugging too cat matrix.json | jq - if jq -e '.["0"].include | length > 0' matrix.json > /dev/null; then + if jq -e '."python-build"["0"].include | length > 0' matrix.json > /dev/null; then # Build matrix has entries echo "any_builds=true" >> $GITHUB_OUTPUT else @@ -169,22 +180,10 @@ jobs: echo "any_builds=false" >> $GITHUB_OUTPUT fi - - name: Check if the `pythonbuild` crate changed - id: check-pythonbuild - env: - BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} - run: | - merge_base=$(git merge-base HEAD "origin/${BASE_REF}") - if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then - echo "changed=false" >> "$GITHUB_OUTPUT" - else - echo "changed=true" >> "$GITHUB_OUTPUT" - fi - build-0: needs: - generate-matrix - - pythonbuild + - crate-build - image # Permissions used for actions/attest-build-provenance permissions: @@ -192,7 +191,7 @@ jobs: attestations: write runs-on: ${{ matrix.runner }} strategy: - matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix-0) }} + matrix: ${{ fromJson(needs.generate-matrix.outputs.python-build-matrix-0) }} fail-fast: false name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }} steps: @@ -208,7 +207,7 @@ jobs: - name: Download pythonbuild uses: actions/download-artifact@v4 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: build - name: Download images @@ -284,7 +283,7 @@ jobs: build-1: needs: - generate-matrix - - pythonbuild + - crate-build - image # Permissions used for actions/attest-build-provenance permissions: @@ -292,7 +291,7 @@ jobs: attestations: write runs-on: ${{ matrix.runner }} strategy: - matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix-1) }} + matrix: ${{ fromJson(needs.generate-matrix.outputs.python-build-matrix-1) }} fail-fast: false name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }} steps: @@ -308,7 +307,7 @@ jobs: - name: Download pythonbuild uses: actions/download-artifact@v4 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: build - name: Download images diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index af9a80f0..1199b398 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -13,11 +13,14 @@ env: FORCE_COLOR: 1 jobs: - pythonbuild: - if: ${{ needs.generate-matrix.outputs.pythonbuild_changed == 'true' || needs.generate-matrix.outputs.any_builds == 'true' || github.ref == 'refs/heads/main' }} + crate-build: needs: - generate-matrix - runs-on: depot-macos-latest + runs-on: ${{ matrix.runner }} + strategy: + matrix: ${{ fromJson(needs.generate-matrix.outputs.crate-build-matrix) }} + fail-fast: false + name: crate / ${{ matrix.arch }} steps: - uses: actions/checkout@v4 @@ -40,15 +43,15 @@ jobs: - name: Upload pythonbuild Executable uses: actions/upload-artifact@v4 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: target/release/pythonbuild generate-matrix: runs-on: ubuntu-latest outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} + crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }} any_builds: ${{ steps.set-matrix.outputs.any_builds }} - pythonbuild_changed: ${{ steps.check-pythonbuild.outputs.changed }} steps: - uses: actions/checkout@v4 with: @@ -64,14 +67,31 @@ jobs: LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")') echo "labels=$LABELS" >> $GITHUB_OUTPUT + - name: Check if the `pythonbuild` crate changed + id: check-pythonbuild + env: + BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} + run: | + merge_base=$(git merge-base HEAD "origin/${BASE_REF}") + if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + - name: Generate build matrix id: set-matrix run: | - uv run ci-matrix.py --platform darwin --labels '${{ steps.get-labels.outputs.labels }}' > matrix.json && echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT + uv run ci-matrix.py --platform darwin --labels '${{ steps.get-labels.outputs.labels }}' ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json + + # Extract python-build matrix + echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT + echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT + # Display the matrix for debugging too cat matrix.json | jq - if jq -e '.include | length > 0' matrix.json > /dev/null; then + if jq -e '."python-build".include | length > 0' matrix.json > /dev/null; then # Build matrix has entries echo "any_builds=true" >> $GITHUB_OUTPUT else @@ -79,22 +99,10 @@ jobs: echo "any_builds=false" >> $GITHUB_OUTPUT fi - - name: Check if the `pythonbuild` crate changed - id: check-pythonbuild - env: - BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} - run: | - merge_base=$(git merge-base HEAD "origin/${BASE_REF}") - if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then - echo "changed=false" >> "$GITHUB_OUTPUT" - else - echo "changed=true" >> "$GITHUB_OUTPUT" - fi - build: needs: - generate-matrix - - pythonbuild + - crate-build # Permissions used for actions/attest-build-provenance permissions: id-token: write @@ -117,7 +125,7 @@ jobs: - name: Download pythonbuild uses: actions/download-artifact@v4 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: build - name: Build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ce803392..6381b3e5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,7 +29,7 @@ jobs: release: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - runs-on: ubuntu-latest-large + runs-on: github-ubuntu-24.04-x86_64-16 steps: - uses: actions/checkout@v4 with: @@ -41,7 +41,7 @@ jobs: - run: just release-dry-run ${{ secrets.GITHUB_TOKEN }} ${{ github.event.inputs.sha }} ${{ github.event.inputs.tag }} if: ${{ github.event.inputs.dry-run == 'true' }} - # Create the release itself. + # Set our identity for git operations (on the latest-release branch). - name: Configure Git identity if: ${{ github.event.inputs.dry-run == 'false' }} run: | @@ -66,14 +66,7 @@ jobs: # Create a GitHub release. - name: Create GitHub Release if: ${{ github.event.inputs.dry-run == 'false' }} - uses: ncipollo/release-action@v1 - with: - tag: ${{ github.event.inputs.tag }} - name: ${{ github.event.inputs.tag }} - prerelease: true - body: TBD - allowUpdates: true - updateOnlyUnreleased: true + run: just release-create ${{ github.event.inputs.tag }} # Uploading the relevant artifact to the GitHub release. - run: just release-run ${{ secrets.GITHUB_TOKEN }} ${{ github.event.inputs.sha }} ${{ github.event.inputs.tag }} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index a7535c68..e285fac3 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -13,11 +13,14 @@ env: FORCE_COLOR: 1 jobs: - pythonbuild: - if: ${{ needs.generate-matrix.outputs.pythonbuild_changed == 'true' || needs.generate-matrix.outputs.any_builds == 'true' || github.ref == 'refs/heads/main' }} + crate-build: needs: - generate-matrix - runs-on: 'windows-2022' + runs-on: ${{ matrix.runner }} + strategy: + matrix: ${{ fromJson(needs.generate-matrix.outputs.crate-build-matrix) }} + fail-fast: false + name: crate / ${{ matrix.arch }} steps: - uses: actions/checkout@v4 @@ -40,15 +43,15 @@ jobs: - name: Upload executable uses: actions/upload-artifact@v4 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} path: target/release/pythonbuild.exe generate-matrix: runs-on: ubuntu-latest outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} + crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }} any_builds: ${{ steps.set-matrix.outputs.any_builds }} - pythonbuild_changed: ${{ steps.check-pythonbuild.outputs.changed }} steps: - uses: actions/checkout@v4 with: @@ -64,14 +67,31 @@ jobs: LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")') echo "labels=$LABELS" >> $GITHUB_OUTPUT + - name: Check if the `pythonbuild` crate changed + id: check-pythonbuild + env: + BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} + run: | + merge_base=$(git merge-base HEAD "origin/${BASE_REF}") + if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + - name: Generate build matrix id: set-matrix run: | - uv run ci-matrix.py --platform windows --labels '${{ steps.get-labels.outputs.labels }}' > matrix.json && echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT + uv run ci-matrix.py --platform windows --labels '${{ steps.get-labels.outputs.labels }}' ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json + + # Extract python-build matrix + echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT + echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT + # Display the matrix for debugging too cat matrix.json | jq - if jq -e '.include | length > 0' matrix.json > /dev/null; then + if jq -e '."python-build".include | length > 0' matrix.json > /dev/null; then # Build matrix has entries echo "any_builds=true" >> $GITHUB_OUTPUT else @@ -79,22 +99,11 @@ jobs: echo "any_builds=false" >> $GITHUB_OUTPUT fi - - name: Check if the `pythonbuild` crate changed - id: check-pythonbuild - env: - BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }} - run: | - merge_base=$(git merge-base HEAD "origin/${BASE_REF}") - if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then - echo "changed=false" >> "$GITHUB_OUTPUT" - else - echo "changed=true" >> "$GITHUB_OUTPUT" - fi - build: + timeout-minutes: 60 needs: - generate-matrix - - pythonbuild + - crate-build # Permissions used for actions/attest-build-provenance permissions: id-token: write @@ -122,7 +131,7 @@ jobs: - name: Download pythonbuild Executable uses: actions/download-artifact@v4 with: - name: pythonbuild + name: ${{ matrix.crate_artifact_name }} # We need to do this before we activate the VC++ environment or else binary packages # don't get compiled properly. diff --git a/Cargo.lock b/Cargo.lock index e6a3dd8a..b0db1676 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1828,15 +1828,14 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", "getrandom 0.2.15", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] @@ -2201,12 +2200,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -2417,9 +2410,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.43.0" +version = "1.43.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "492a604e2fd7f814268a378409e6c92b5525d747d10db9a229723f55a417958c" dependencies = [ "backtrace", "bytes", diff --git a/Cargo.toml b/Cargo.toml index e3826630..82f02982 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ sha2 = "0.10.8" tar = "0.4.40" tempfile = "3.10.0" text-stub-library = "0.9.0" -tokio = "1.36.0" +tokio = "1.43.1" url = "2.5.0" version-compare = "0.1.1" zip = "0.6.6" diff --git a/Justfile b/Justfile index 0255bd22..c9b8167f 100644 --- a/Justfile +++ b/Justfile @@ -67,6 +67,28 @@ release-set-latest-release tag: echo "No changes to commit." fi +# Create a GitHub release object, or reuse an existing prerelease. +release-create tag: + #!/usr/bin/env bash + set -euo pipefail + prerelease_exists=$(gh release view {{tag}} --json isPrerelease -t '{{{{.isPrerelease}}' 2>&1 || true) + case "$prerelease_exists" in + true) + echo "note: updating existing prerelease {{tag}}" + ;; + false) + echo "error: release {{tag}} already exists" + exit 1 + ;; + "release not found") + gh release create {{tag}} --prerelease --notes TBD --verify-tag + ;; + *) + echo "error: unexpected gh cli output: $prerelease_exists" + exit 1 + ;; + esac + # Perform the release job. Assumes that the GitHub Release has been created. release-run token commit tag: #!/bin/bash diff --git a/ci-matrix.py b/ci-matrix.py index c9bcccee..91cfa953 100644 --- a/ci-matrix.py +++ b/ci-matrix.py @@ -20,6 +20,21 @@ CI_MATRIX_SIZE_LIMIT = 256 # The maximum size of a matrix in GitHub Actions +# Docker images for building toolchains and dependencies +DOCKER_BUILD_IMAGES = [ + {"name": "build", "arch": "x86_64"}, + {"name": "build.cross", "arch": "x86_64"}, + {"name": "build.cross-riscv64", "arch": "x86_64"}, + {"name": "build.debian9", "arch": "aarch64"}, + {"name": "gcc", "arch": "x86_64"}, + {"name": "gcc.debian9", "arch": "aarch64"}, +] + + +def crate_artifact_name(platform: str, arch: str) -> str: + return f"crate-{platform}-{arch}" + + def meets_conditional_version(version: str, min_version: str) -> bool: return Version(version) >= Version(min_version) @@ -89,12 +104,87 @@ def should_include_entry(entry: dict[str, str], filters: dict[str, set[str]]) -> return True -def generate_matrix_entries( +def generate_docker_matrix_entries( + runners: dict[str, Any], + platform_filter: Optional[str] = None, +) -> list[dict[str, str]]: + """Generate matrix entries for docker image builds.""" + if platform_filter and platform_filter != "linux": + return [] + + matrix_entries = [] + for image in DOCKER_BUILD_IMAGES: + # Find appropriate runner for Linux platform with the specified architecture + runner = find_runner(runners, "linux", image["arch"], False) + + entry = { + "name": image["name"], + "arch": image["arch"], + "runner": runner, + } + matrix_entries.append(entry) + + return matrix_entries + + +def generate_crate_build_matrix_entries( + python_entries: list[dict[str, str]], + runners: dict[str, Any], + config: dict[str, Any], + force_crate_build: bool = False, + platform_filter: Optional[str] = None, +) -> list[dict[str, str]]: + """Generate matrix entries for crate builds based on python build matrix.""" + needed_builds = set() + for entry in python_entries: + # The crate build will need to match the runner's architecture + runner = runners[entry["runner"]] + needed_builds.add((entry["platform"], runner["arch"])) + + # If forcing crate build, also include all possible native builds + if force_crate_build: + for platform, platform_config in config.items(): + # Filter by platform if specified + if platform_filter and platform != platform_filter: + continue + + for target_config in platform_config.values(): + # Only include if native (run: true means native) + if not target_config.get("run"): + continue + + arch = target_config["arch"] + needed_builds.add((platform, arch)) + + # Create matrix entries for each needed build + return [ + { + "platform": platform, + "arch": arch, + # Use the GitHub runner for Windows, because the Depot one is + # missing a Rust toolchain. On Linux, it's important that the the + # `python-build` runner matches the `crate-build` runner because of + # GLIBC version mismatches. + "runner": find_runner( + runners, platform, arch, True if platform == "windows" else False + ), + "crate_artifact_name": crate_artifact_name( + platform, + arch, + ), + } + for platform, arch in needed_builds + if not platform_filter or platform == platform_filter + ] + + +def generate_python_build_matrix_entries( config: dict[str, Any], runners: dict[str, Any], platform_filter: Optional[str] = None, label_filters: Optional[dict[str, set[str]]] = None, ) -> list[dict[str, str]]: + """Generate matrix entries for python builds.""" matrix_entries = [] for platform, platform_config in config.items(): @@ -102,13 +192,13 @@ def generate_matrix_entries( continue for target_triple, target_config in platform_config.items(): - add_matrix_entries_for_config( + add_python_build_entries_for_config( matrix_entries, target_triple, target_config, platform, runners, - label_filters.get("directives", set()), + label_filters.get("directives", set()) if label_filters else set(), ) # Apply label filters if present @@ -122,10 +212,12 @@ def generate_matrix_entries( return matrix_entries -def find_runner(runners: dict[str, Any], platform: str, arch: str) -> str: +def find_runner(runners: dict[str, Any], platform: str, arch: str, free: bool) -> str: # Find a matching platform first match_platform = [ - runner for runner in runners if runners[runner]["platform"] == platform + runner + for runner in runners + if runners[runner]["platform"] == platform and runners[runner]["free"] == free ] # Then, find a matching architecture @@ -141,10 +233,12 @@ def find_runner(runners: dict[str, Any], platform: str, arch: str) -> str: if match_platform: return match_platform[0] - raise RuntimeError(f"No runner found for platform {platform!r} and arch {arch!r}") + raise RuntimeError( + f"No runner found for platform {platform!r} and arch {arch!r} with free={free}" + ) -def add_matrix_entries_for_config( +def add_python_build_entries_for_config( matrix_entries: list[dict[str, str]], target_triple: str, config: dict[str, Any], @@ -152,10 +246,11 @@ def add_matrix_entries_for_config( runners: dict[str, Any], directives: set[str], ) -> None: + """Add python build matrix entries for a specific target configuration.""" python_versions = config["python_versions"] build_options = config["build_options"] arch = config["arch"] - runner = find_runner(runners, platform, arch) + runner = find_runner(runners, platform, arch, False) # Create base entry that will be used for all variants base_entry = { @@ -166,6 +261,8 @@ def add_matrix_entries_for_config( # If `run` is in the config, use that — otherwise, default to if the # runner architecture matches the build architecture "run": str(config.get("run", runners[runner]["arch"] == arch)).lower(), + # Use the crate artifact built for the runner's architecture + "crate_artifact_name": crate_artifact_name(platform, runners[runner]["arch"]), } # Add optional fields if they exist @@ -233,6 +330,17 @@ def parse_args() -> argparse.Namespace: action="store_true", help="If only free runners should be used.", ) + parser.add_argument( + "--force-crate-build", + action="store_true", + help="Force crate builds to be included even without python builds.", + ) + parser.add_argument( + "--matrix-type", + choices=["python-build", "docker-build", "crate-build", "all"], + default="all", + help="Which matrix types to generate (default: all)", + ) return parser.parse_args() @@ -254,36 +362,70 @@ def main() -> None: if runner_config.get("free") } - entries = generate_matrix_entries( + result = {} + + # Generate python build entries + python_entries = generate_python_build_matrix_entries( config, runners, args.platform, labels, ) - if args.max_shards: - matrix = {} - shards = (len(entries) // CI_MATRIX_SIZE_LIMIT) + 1 - if shards > args.max_shards: - print( - f"error: matrix of size {len(entries)} requires {shards} shards, but the maximum is {args.max_shards}; consider increasing `--max-shards`", - file=sys.stderr, - ) - sys.exit(1) - for shard in range(args.max_shards): - shard_entries = entries[ - shard * CI_MATRIX_SIZE_LIMIT : (shard + 1) * CI_MATRIX_SIZE_LIMIT - ] - matrix[str(shard)] = {"include": shard_entries} - else: - if len(entries) > CI_MATRIX_SIZE_LIMIT: - print( - f"warning: matrix of size {len(entries)} exceeds limit of {CI_MATRIX_SIZE_LIMIT} but sharding is not enabled; consider setting `--max-shards`", - file=sys.stderr, + # Output python-build matrix if requested + if args.matrix_type in ["python-build", "all"]: + if args.max_shards: + python_build_matrix = {} + shards = (len(python_entries) // CI_MATRIX_SIZE_LIMIT) + 1 + if shards > args.max_shards: + print( + f"error: python-build matrix of size {len(python_entries)} requires {shards} shards, but the maximum is {args.max_shards}; consider increasing `--max-shards`", + file=sys.stderr, + ) + sys.exit(1) + for shard in range(args.max_shards): + shard_entries = python_entries[ + shard * CI_MATRIX_SIZE_LIMIT : (shard + 1) * CI_MATRIX_SIZE_LIMIT + ] + python_build_matrix[str(shard)] = {"include": shard_entries} + result["python-build"] = python_build_matrix + else: + if len(python_entries) > CI_MATRIX_SIZE_LIMIT: + print( + f"warning: python-build matrix of size {len(python_entries)} exceeds limit of {CI_MATRIX_SIZE_LIMIT} but sharding is not enabled; consider setting `--max-shards`", + file=sys.stderr, + ) + result["python-build"] = {"include": python_entries} + + # Generate docker-build matrix if requested + # Only include docker builds if there are Linux python builds + if args.matrix_type in ["docker-build", "all"]: + # Check if we have any Linux python builds + has_linux_builds = any( + entry.get("platform") == "linux" for entry in python_entries + ) + + # If no platform filter or explicitly requesting docker-build only, include docker builds + # Otherwise, only include if there are Linux python builds + if args.matrix_type == "docker-build" or has_linux_builds: + docker_entries = generate_docker_matrix_entries( + runners, + args.platform, ) - matrix = {"include": entries} - - print(json.dumps(matrix)) + result["docker-build"] = {"include": docker_entries} + + # Generate crate-build matrix if requested + if args.matrix_type in ["crate-build", "all"]: + crate_entries = generate_crate_build_matrix_entries( + python_entries, + runners, + config, + args.force_crate_build, + args.platform, + ) + result["crate-build"] = {"include": crate_entries} + + print(json.dumps(result)) if __name__ == "__main__": diff --git a/ci-runners.yaml b/ci-runners.yaml index aeb0e5ca..dae6aabc 100644 --- a/ci-runners.yaml +++ b/ci-runners.yaml @@ -5,11 +5,10 @@ depot-ubuntu-22.04: platform: linux free: false -# TODO: Enable this runner to perform native builds for aarch64 -# depot-ubuntu-22.04-arm: -# arch: aarch64 -# platform: linux -# free: false +depot-ubuntu-22.04-arm: + arch: aarch64 + platform: linux + free: false depot-macos-latest: arch: x86_64 @@ -26,6 +25,11 @@ macos-latest: platform: darwin free: true +depot-windows-2022-8: + arch: x86_64 + platform: windows + free: false + windows-latest-large: arch: x86_64 platform: windows @@ -35,3 +39,8 @@ windows-latest: arch: x86_64 platform: windows free: true + +windows-11-arm: + arch: aarch64 + platform: windows + free: false diff --git a/ci-targets.yaml b/ci-targets.yaml index 70078e87..c59d5b7f 100644 --- a/ci-targets.yaml +++ b/ci-targets.yaml @@ -50,13 +50,11 @@ linux: - "3.14" build_options: - debug - - noopt - - lto + - pgo+lto build_options_conditional: - options: - freethreaded+debug - - freethreaded+noopt - - freethreaded+lto + - freethreaded+pgo+lto minimum-python-version: "3.13" armv7-unknown-linux-gnueabi: @@ -384,3 +382,21 @@ windows: - options: - freethreaded+pgo minimum-python-version: "3.13" + + aarch64-pc-windows-msvc: + arch: aarch64 + vcvars: vcvarsamd64_arm64.bat + python_versions: + # On 3.9 / 3.10, `_tkinter` is failing to be included in the build + # - "3.9" + # - "3.10" + - "3.11" + - "3.12" + - "3.13" + - "3.14" + build_options: + - pgo + build_options_conditional: + - options: + - freethreaded+pgo + minimum-python-version: "3.13" diff --git a/cpython-unix/Makefile b/cpython-unix/Makefile index 0e859784..6e4b0070 100644 --- a/cpython-unix/Makefile +++ b/cpython-unix/Makefile @@ -66,27 +66,29 @@ TOOLCHAIN_DEPENDS := \ PYTHON_DEP_DEPENDS := \ $(OUTDIR)/targets/$(TARGET_TRIPLE) \ - $(if $(PYBUILD_NO_DOCKER),,$(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).tar) \ + $(if $(PYBUILD_NO_DOCKER),,$(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).$(HOST_PLATFORM).tar) \ $(TOOLCHAIN_DEPENDS) \ $(NULL) +HOST_PYTHON_DEPENDS := $(OUTDIR)/cpython-$(PYTHON_MAJOR_VERSION)-$(CPYTHON_$(PYTHON_MAJOR_VERSION)_VERSION)-$(HOST_PLATFORM).tar + default: $(OUTDIR)/cpython-$(CPYTHON_$(PYTHON_MAJOR_VERSION)_VERSION)-$(PACKAGE_SUFFIX).tar ifndef PYBUILD_NO_DOCKER -$(OUTDIR)/image-%.tar: $(OUTDIR)/%.Dockerfile +$(OUTDIR)/image-%.$(HOST_PLATFORM).tar: $(OUTDIR)/%.Dockerfile $(RUN_BUILD) --toolchain image-$* endif -$(OUTDIR)/binutils-$(BINUTILS_VERSION)-$(HOST_PLATFORM).tar: $(OUTDIR)/image-gcc.tar $(HERE)/build-binutils.sh - $(RUN_BUILD) --toolchain binutils +$(OUTDIR)/binutils-$(BINUTILS_VERSION)-$(HOST_PLATFORM).tar: $(HERE)/build-binutils.sh + $(RUN_BUILD) --toolchain --docker-image $(DOCKER_IMAGE_GCC) binutils $(OUTDIR)/$(CLANG_FILENAME): $(RUN_BUILD) --toolchain clang --target-triple $(TARGET_TRIPLE) $(OUTDIR)/musl-$(MUSL_VERSION)-$(HOST_PLATFORM).tar: $(BASE_TOOLCHAIN_DEPENDS) $(HERE)/build-musl.sh - $(RUN_BUILD) --toolchain musl + $(RUN_BUILD) --toolchain musl --docker-image $(DOCKER_IMAGE_GCC) -ifeq ($(HOST_PLATFORM),linux64) +ifeq ($(HOST_PLATFORM),linux_x86_64) TOOLCHAIN_TARGET := $(OUTDIR)/musl-$(MUSL_VERSION)-$(HOST_PLATFORM).tar else TOOLCHAIN_TARGET := @@ -117,28 +119,18 @@ $(OUTDIR)/bzip2-$(BZIP2_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $( $(OUTDIR)/expat-$(EXPAT_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-expat.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) expat -$(OUTDIR)/inputproto-$(INPUTPROTO_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-inputproto.sh - $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) inputproto - -$(OUTDIR)/kbproto-$(KBPROTO_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-kbproto.sh - $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) kbproto - $(OUTDIR)/libffi-3.3-$(LIBFFI_3.3_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libffi-3.3.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libffi-3.3 $(OUTDIR)/libffi-$(LIBFFI_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libffi.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libffi -$(OUTDIR)/libpthread-stubs-$(LIBPTHREAD_STUBS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libpthread-stubs.sh $(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).tar +$(OUTDIR)/libpthread-stubs-$(LIBPTHREAD_STUBS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libpthread-stubs.sh $(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).$(HOST_PLATFORM).tar $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libpthread-stubs LIBX11_DEPENDS = \ $(PYTHON_DEP_DEPENDS) \ $(HERE)/build-libX11.sh \ - $(OUTDIR)/xproto-$(XPROTO_VERSION)-$(PACKAGE_SUFFIX).tar \ - $(OUTDIR)/xextproto-$(XEXTPROTO_VERSION)-$(PACKAGE_SUFFIX).tar \ - $(OUTDIR)/kbproto-$(KBPROTO_VERSION)-$(PACKAGE_SUFFIX).tar \ - $(OUTDIR)/inputproto-$(INPUTPROTO_VERSION)-$(PACKAGE_SUFFIX).tar \ $(OUTDIR)/libxcb-$(LIBXCB_VERSION)-$(PACKAGE_SUFFIX).tar \ $(OUTDIR)/xtrans-$(XTRANS_VERSION)-$(PACKAGE_SUFFIX).tar \ $(OUTDIR)/xorgproto-$(XORGPROTO_VERSION)-$(PACKAGE_SUFFIX).tar \ @@ -151,7 +143,7 @@ LIBXAU_DEPENDS = \ $(PYTHON_DEP_DEPENDS) \ $(HERE)/build-libXau.sh \ $(OUTDIR)/x11-util-macros-$(X11_UTIL_MACROS_VERSION)-$(PACKAGE_SUFFIX).tar \ - $(OUTDIR)/xproto-$(XPROTO_VERSION)-$(PACKAGE_SUFFIX).tar \ + $(OUTDIR)/xorgproto-$(XORGPROTO_VERSION)-$(PACKAGE_SUFFIX).tar \ $(NULL) $(OUTDIR)/libXau-$(LIBXAU_VERSION)-$(PACKAGE_SUFFIX).tar: $(LIBXAU_DEPENDS) @@ -159,16 +151,16 @@ $(OUTDIR)/libXau-$(LIBXAU_VERSION)-$(PACKAGE_SUFFIX).tar: $(LIBXAU_DEPENDS) LIBXCB_DEPENDS = \ $(PYTHON_DEP_DEPENDS) \ + $(HOST_PYTHON_DEPENDS) \ $(HERE)/build-libxcb.sh \ - $(OUTDIR)/image-$(DOCKER_IMAGE_XCB).tar \ $(OUTDIR)/xcb-proto-$(XCB_PROTO_VERSION)-$(PACKAGE_SUFFIX).tar \ $(OUTDIR)/libXau-$(LIBXAU_VERSION)-$(PACKAGE_SUFFIX).tar \ - $(OUTDIR)/xproto-$(XPROTO_VERSION)-$(PACKAGE_SUFFIX).tar \ + $(OUTDIR)/xorgproto-$(XORGPROTO_VERSION)-$(PACKAGE_SUFFIX).tar \ $(OUTDIR)/libpthread-stubs-$(LIBPTHREAD_STUBS_VERSION)-$(PACKAGE_SUFFIX).tar \ $(NULL) $(OUTDIR)/libxcb-$(LIBXCB_VERSION)-$(PACKAGE_SUFFIX).tar: $(LIBXCB_DEPENDS) - $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_XCB) libxcb + $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) --python-host-version $(PYBUILD_PYTHON_VERSION) libxcb $(OUTDIR)/m4-$(M4_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-m4.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) m4 @@ -214,13 +206,14 @@ $(OUTDIR)/tix-$(TIX_VERSION)-$(PACKAGE_SUFFIX).tar: $(TIX_DEPENDS) $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) tix TK_DEPENDS = \ + $(HOST_PYTHON_DEPENDS) \ $(HERE)/build-tk.sh \ $(OUTDIR)/tcl-$(TCL_VERSION)-$(PACKAGE_SUFFIX).tar \ $(if $(NEED_LIBX11),$(OUTDIR)/libX11-$(LIBX11_VERSION)-$(PACKAGE_SUFFIX).tar) \ $(NULL) $(OUTDIR)/tk-$(TK_VERSION)-$(PACKAGE_SUFFIX).tar: $(TK_DEPENDS) - $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_XCB) tk + $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) --python-host-version $(PYBUILD_PYTHON_VERSION) tk $(OUTDIR)/uuid-$(UUID_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-uuid.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) uuid @@ -228,18 +221,12 @@ $(OUTDIR)/uuid-$(UUID_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HE $(OUTDIR)/x11-util-macros-$(X11_UTIL_MACROS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-x11-util-macros.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) x11-util-macros -$(OUTDIR)/xcb-proto-$(XCB_PROTO_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-xcb-proto.sh - $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_XCB) xcb-proto - -$(OUTDIR)/xextproto-$(XEXTPROTO_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-xextproto.sh - $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) xextproto +$(OUTDIR)/xcb-proto-$(XCB_PROTO_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HOST_PYTHON_DEPENDS) $(HERE)/build-xcb-proto.sh + $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) --python-host-version $(PYBUILD_PYTHON_VERSION) xcb-proto $(OUTDIR)/xorgproto-$(XORGPROTO_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-xorgproto.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) xorgproto -$(OUTDIR)/xproto-$(XPROTO_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-xproto.sh - $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) xproto - $(OUTDIR)/xtrans-$(XTRANS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-xtrans.sh $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) xtrans diff --git a/cpython-unix/base.Dockerfile b/cpython-unix/base.Dockerfile index 58016550..7e666e04 100644 --- a/cpython-unix/base.Dockerfile +++ b/cpython-unix/base.Dockerfile @@ -29,10 +29,6 @@ RUN for s in debian_jessie debian_jessie-updates debian-security_jessie/updates; echo 'Acquire::Retries "5";'; \ ) > /etc/apt/apt.conf.d/99cpython-portable -RUN ( echo 'amd64'; \ - echo 'i386'; \ - ) > /var/lib/dpkg/arch - # apt iterates all available file descriptors up to rlim_max and calls # fcntl(fd, F_SETFD, FD_CLOEXEC). This can result in millions of system calls # (we've seen 1B in the wild) and cause operations to take seconds to minutes. diff --git a/cpython-unix/base.debian9.Dockerfile b/cpython-unix/base.debian9.Dockerfile new file mode 100644 index 00000000..1b47b35a --- /dev/null +++ b/cpython-unix/base.debian9.Dockerfile @@ -0,0 +1,38 @@ +# Debian Stretch. +FROM debian@sha256:c5c5200ff1e9c73ffbf188b4a67eb1c91531b644856b4aefe86a58d2f0cb05be +MAINTAINER Gregory Szorc + +RUN groupadd -g 1000 build && \ + useradd -u 1000 -g 1000 -d /build -s /bin/bash -m build && \ + mkdir /tools && \ + chown -R build:build /build /tools + +ENV HOME=/build \ + SHELL=/bin/bash \ + USER=build \ + LOGNAME=build \ + HOSTNAME=builder \ + DEBIAN_FRONTEND=noninteractive + +CMD ["/bin/bash", "--login"] +WORKDIR '/build' + +RUN for s in debian_stretch debian_stretch-updates debian-security_stretch/updates; do \ + echo "deb http://snapshot.debian.org/archive/${s%_*}/20230423T032736Z/ ${s#*_} main"; \ + done > /etc/apt/sources.list && \ + ( echo 'quiet "true";'; \ + echo 'APT::Get::Assume-Yes "true";'; \ + echo 'APT::Install-Recommends "false";'; \ + echo 'Acquire::Check-Valid-Until "false";'; \ + echo 'Acquire::Retries "5";'; \ + ) > /etc/apt/apt.conf.d/99cpython-portable + +# apt iterates all available file descriptors up to rlim_max and calls +# fcntl(fd, F_SETFD, FD_CLOEXEC). This can result in millions of system calls +# (we've seen 1B in the wild) and cause operations to take seconds to minutes. +# Setting a fd limit mitigates. +# +# Attempts at enforcing the limit globally via /etc/security/limits.conf and +# /root/.bashrc were not successful. Possibly because container image builds +# don't perform a login or use a shell the way we expect. +RUN ulimit -n 10000 && apt-get update diff --git a/cpython-unix/build-binutils.sh b/cpython-unix/build-binutils.sh index b287e2e1..2bb89364 100755 --- a/cpython-unix/build-binutils.sh +++ b/cpython-unix/build-binutils.sh @@ -5,26 +5,21 @@ set -ex -ROOT=$(pwd) -SCCACHE="${ROOT}/sccache" - cd /build tar -xf binutils-${BINUTILS_VERSION}.tar.xz mkdir binutils-objdir pushd binutils-objdir -EXTRA_VARS= - -if [ -x "${SCCACHE}" ]; then - "${SCCACHE}" --start-server - export CC="${SCCACHE} /usr/bin/gcc" - export STAGE_CC_WRAPPER="${SCCACHE}" +if [ "$(uname -m)" = "x86_64" ]; then + triple="x86_64-unknown-linux-gnu" +else + triple="aarch64-unknown-linux-gnu" fi # gprofng requires a bison newer than what we have. So just disable it. ../binutils-${BINUTILS_VERSION}/configure \ - --build=x86_64-unknown-linux-gnu \ + --build=${triple} \ --prefix=/tools/host \ --enable-plugins \ --enable-gprofng=no \ diff --git a/cpython-unix/build-cpython-host.sh b/cpython-unix/build-cpython-host.sh index 3cfa3ac5..99b021d7 100755 --- a/cpython-unix/build-cpython-host.sh +++ b/cpython-unix/build-cpython-host.sh @@ -22,7 +22,7 @@ export trailer_m4=${TOOLS_PATH}/host/share/autoconf/autoconf/trailer.m4 # The share/autoconf/autom4te.cfg file also hard-codes some paths. Rewrite # those to the real tools path. -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then sed_args="-i '' -e" else sed_args="-i" diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh index 68d0bde2..ce88e6c7 100755 --- a/cpython-unix/build-cpython.sh +++ b/cpython-unix/build-cpython.sh @@ -33,7 +33,7 @@ export trailer_m4=${TOOLS_PATH}/host/share/autoconf/autoconf/trailer.m4 # The share/autoconf/autom4te.cfg file also hard-codes some paths. Rewrite # those to the real tools path. -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then sed_args=(-i '' -e) else sed_args=(-i) @@ -59,7 +59,7 @@ cat Makefile.extra pushd Python-${PYTHON_VERSION} # configure doesn't support cross-compiling on Apple. Teach it. -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then patch -p1 -i ${ROOT}/patch-apple-cross-3.13.patch elif [ "${PYTHON_MAJMIN_VERSION}" = "3.12" ]; then @@ -76,6 +76,13 @@ if [ -n "${CROSS_COMPILING}" ]; then fi fi +# `uuid.getnode()` is not stable on our libuuid, CPython should fallback to another method +# Cherry-pick https://github.com/python/cpython/pull/134704 until it is released +# We could backport this to more versions too, it won't be done by the upstream +if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" && -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_13}" ]]; then + patch -p1 -i ${ROOT}/patch-uuid-getnode-stable-3.13.patch +fi + # This patch is slightly different on Python 3.10+. if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_10}" ]; then patch -p1 -i ${ROOT}/patch-xopen-source-ios.patch @@ -91,6 +98,9 @@ fi # Configure nerfs RUNSHARED when cross-compiling, which prevents PGO from running when # we can in fact run the target binaries (e.g. x86_64 host and i686 target). Undo that. +# TODO this may not be needed after removing support for i686 builds. But it +# may still be useful since CPython's definition of cross-compiling has historically +# been very liberal and kicks in when it arguably shouldn't. if [ -n "${CROSS_COMPILING}" ]; then if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]; then patch -p1 -i ${ROOT}/patch-dont-clear-runshared-14.patch @@ -159,7 +169,7 @@ fi # linked modules. But those libraries should only get linked into libpython, not the # executable. This behavior is kinda suspect on all platforms, as it could be adding # library dependencies that shouldn't need to be there. -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then if [ "${PYTHON_MAJMIN_VERSION}" = "3.9" ]; then patch -p1 -i ${ROOT}/patch-python-link-modules-3.9.patch elif [ "${PYTHON_MAJMIN_VERSION}" = "3.10" ]; then @@ -214,7 +224,7 @@ fi # macOS. On older versions, we need to hack up readline.c to build against # libedit. This patch breaks older libedit (as seen on macOS) so don't apply # on macOS. -if [[ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_9}" && "${PYBUILD_PLATFORM}" != "macos" ]]; then +if [[ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_9}" && "${PYBUILD_PLATFORM}" != macos* ]]; then # readline.c assumes that a modern readline API version has a free_history_entry(). # but libedit does not. Change the #ifdef accordingly. # @@ -271,6 +281,12 @@ if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_12}" ]; then # https://github.com/python/cpython/issues/128514 patch -p1 -i ${ROOT}/patch-configure-bolt-apply-flags-128514.patch + # Disable unsafe identical code folding. Objects/typeobject.c + # update_one_slot requires that wrap_binaryfunc != wrap_binaryfunc_l, + # despite the functions being identical. + # https://github.com/python/cpython/pull/134642 + patch -p1 -i ${ROOT}/patch-configure-bolt-icf-safe.patch + # Tweak --skip-funcs to work with our toolchain. patch -p1 -i ${ROOT}/patch-configure-bolt-skip-funcs.patch fi @@ -298,17 +314,6 @@ if [ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_10}" ]; then patch -p1 -i ${ROOT}/patch-configure-crypt-no-modify-libs.patch fi -# We patched configure.ac above. Reflect those changes. -autoconf - -# configure assumes cross compiling when host != target and doesn't provide a way to -# override. Our target triple normalization may lead configure into thinking we -# aren't cross-compiling when we are. So force a static "yes" value when our -# build system says we are cross-compiling. -if [ -n "${CROSS_COMPILING}" ]; then - patch -p1 -i ${ROOT}/patch-force-cross-compile.patch -fi - # BOLT instrumented binaries segfault in some test_embed tests for unknown reasons. # On 3.12 (minimum BOLT version), the segfault causes the test harness to # abort and BOLT optimization uses the partial test results. On 3.13, the segfault @@ -328,13 +333,13 @@ CFLAGS=${CFLAGS//-fvisibility=hidden/} # But some symbols from some dependency libraries are still non-hidden for some # reason. We force the linker to do our bidding. -if [ "${PYBUILD_PLATFORM}" != "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then LDFLAGS="${LDFLAGS} -Wl,--exclude-libs,ALL" fi EXTRA_CONFIGURE_FLAGS= -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then CFLAGS="${CFLAGS} -I${TOOLS_PATH}/deps/include/uuid" # Prevent using symbols not supported by current macOS SDK target. @@ -343,7 +348,7 @@ fi # Always build against libedit instead of the default of readline. # macOS always uses the system libedit, so no tweaks are needed. -if [ "${PYBUILD_PLATFORM}" != "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then # CPython 3.10 introduced proper configure support for libedit, so add configure # flag there. if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_10}" ]; then @@ -385,6 +390,22 @@ CONFIGURE_FLAGS=" ${EXTRA_CONFIGURE_FLAGS}" +# Build a libpython3.x.so, but statically link the interpreter against +# libpython. +# +# For now skip this on macos, because it causes some linker failures. Note that +# this patch mildly conflicts with the macos-only patch-python-link-modules +# applied above, so you will need to resolve that conflict if you re-enable +# this for macos. +if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then + if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_12}" ]; then + patch -p1 -i "${ROOT}/patch-python-configure-add-enable-static-libpython-for-interpreter.patch" + else + patch -p1 -i "${ROOT}/patch-python-configure-add-enable-static-libpython-for-interpreter-${PYTHON_MAJMIN_VERSION}.patch" + fi + CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --enable-static-libpython-for-interpreter" +fi + if [ "${CC}" = "musl-clang" ]; then # In order to build the _blake2 extension module with SSE3+ instructions, we need # musl-clang to find headers that provide access to the intrinsics, as they are not @@ -450,12 +471,24 @@ if [ -n "${CPYTHON_OPTIMIZED}" ]; then # Allow users to enable the experimental JIT on 3.13+ if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]]; then - # The JIT build is failing on macOS due to compiler errors - # Only enable on Linux / 3.13 until that's fixed upstream - if [[ "${PYBUILD_PLATFORM}" != "macos" ]]; then + # Do not enable on x86-64 macOS because the JIT requires macOS 11+ and we are currently + # using 10.15 as a miniumum version. + # Do not enable when free-threading, because they're not compatible yet. + if [[ ! ( "${TARGET_TRIPLE}" == "x86_64-apple-darwin" || -n "${CPYTHON_FREETHREADED}" ) ]]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --enable-experimental-jit=yes-off" fi + # Respect CFLAGS during JIT compilation. + # + # Backports https://github.com/python/cpython/pull/134276 which we're trying to get released + # in 3.14, but is currently only in 3.15+. + if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]; then + patch -p1 -i ${ROOT}/patch-jit-cflags-314.patch + elif [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then + patch -p1 -i ${ROOT}/patch-jit-cflags-313.patch + fi + + if [[ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_13}" ]]; then # On 3.13, LLVM 18 is hard-coded into the configure script. Override it to our toolchain # version. @@ -479,7 +512,7 @@ if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_11}" ]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --with-build-python=${TOOLS_PATH}/host/bin/python${PYTHON_MAJMIN_VERSION}" fi -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then # Configure may detect libintl from non-system sources, such # as Homebrew or MacPorts. So nerf the check to prevent this. CONFIGURE_FLAGS="${CONFIGURE_FLAGS} ac_cv_lib_intl_textdomain=no" @@ -549,7 +582,7 @@ if [ "${PYBUILD_PLATFORM}" = "macos" ]; then fi # ptsrname_r is only available in SDK 13.4+, but we target a lower version for compatibility. -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} ac_cv_func_ptsname_r=no" fi @@ -561,18 +594,33 @@ fi # On 3.14+ `test_strftime_y2k` fails when cross-compiling for `x86_64_v2` and `x86_64_v3` targets on # Linux, so we ignore it. See https://github.com/python/cpython/issues/128104 -if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" && -n "${CROSS_COMPILING}" && "${PYBUILD_PLATFORM}" != "macos" ]]; then +if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" && -n "${CROSS_COMPILING}" && "${PYBUILD_PLATFORM}" != macos* ]]; then export PROFILE_TASK='-m test --pgo --ignore test_strftime_y2k' fi +# ./configure tries to auto-detect whether it can build 128-bit and 256-bit SIMD helpers for HACL, +# but on x86-64 that requires v2 and v3 respectively, and on arm64 the performance is bad as noted +# in the comments, so just don't even try. (We should check if we can make this conditional) +if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]]; then + patch -p1 -i "${ROOT}/patch-python-configure-hacl-no-simd.patch" +fi + # We use ndbm on macOS and BerkeleyDB elsewhere. -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --with-dbmliborder=ndbm" else CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --with-dbmliborder=bdb" fi if [ -n "${CROSS_COMPILING}" ]; then + # configure assumes cross compiling when host != target and doesn't + # provide a way to override. Our target triple normalization may + # lead configure into thinking we aren't cross-compiling when we + # are. So force a static "yes" value when our build system says we + # are cross-compiling. + # See also https://savannah.gnu.org/support/?110348 + CONFIGURE_FLAGS="${CONFIGURE_FLAGS} cross_compiling=yes" + # configure doesn't like a handful of scenarios when cross-compiling. # # getaddrinfo buggy test fails for some reason. So we short-circuit it. @@ -586,12 +634,34 @@ if [ -n "${CROSS_COMPILING}" ]; then # python will end up with the time.tzset function or not. All linux targets, # however, should have a working tzset function via libc. So we manually # indicate this to the configure script. - if [ "${PYBUILD_PLATFORM}" != "macos" ]; then + if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} ac_cv_working_tzset=yes" fi + + # Also, it cannot detect whether the compiler supports -pthread or + # not, and conservatively defaults to no, which is not the right + # default on relatively modern compilers. + CONFIGURE_FLAGS="${CONFIGURE_FLAGS} ac_cv_pthread=yes" + + # TODO: There are probably more of these, see #399. fi -CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS LDFLAGS=$LDFLAGS \ +# We patched configure.ac above. Reflect those changes. +autoconf + +# Ensure `CFLAGS` are propagated to JIT compilation for 3.13+ (note this variable has no effect on +# 3.12 and earlier) +CFLAGS_JIT="${CFLAGS}" + +# In 3.14+, the JIT compiler on x86-64 Linux uses a model that conflicts with `-fPIC`, so strip it +# from the flags. See: +# - https://github.com/python/cpython/issues/135690 +# - https://github.com/python/cpython/pull/130097 +if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" && "${TARGET_TRIPLE}" == x86_64* ]]; then + CFLAGS_JIT="${CFLAGS_JIT//-fPIC/}" +fi + +CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS CFLAGS_JIT=$CFLAGS_JIT LDFLAGS=$LDFLAGS \ ./configure ${CONFIGURE_FLAGS} # Supplement produced Makefile with our modifications. @@ -628,7 +698,7 @@ fi # This ensures we can run the binary in any location without # LD_LIBRARY_PATH pointing to the directory containing libpython. if [ "${PYBUILD_SHARED}" = "1" ]; then - if [ "${PYBUILD_PLATFORM}" = "macos" ]; then + if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then # There's only 1 dylib produced on macOS and it has the binary suffix. LIBPYTHON_SHARED_LIBRARY_BASENAME=libpython${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}.dylib LIBPYTHON_SHARED_LIBRARY=${ROOT}/out/python/install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} @@ -656,45 +726,106 @@ if [ "${PYBUILD_SHARED}" = "1" ]; then -change /install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} @executable_path/../lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} \ ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX} fi - else + else # (not macos) LIBPYTHON_SHARED_LIBRARY_BASENAME=libpython${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}.so.1.0 LIBPYTHON_SHARED_LIBRARY=${ROOT}/out/python/install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} - if [ "${CC}" == "musl-clang" ]; then - # musl does not support $ORIGIN in DT_NEEDED, so we use RPATH instead. This could be - # problematic, i.e., we could load the shared library from the wrong location if - # `LD_LIBRARY_PATH` is set, but there's not a clear alternative at this time. The - # long term solution is probably to statically link to libpython instead. - patchelf --set-rpath "\$ORIGIN/../lib" \ - ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION} + # Although we are statically linking libpython, some extension + # modules link against libpython.so even though they are not + # supposed to do that. If you try to import them on an + # interpreter statically linking libpython, all the symbols they + # need are resolved from the main program (because neither glibc + # nor musl has two-level namespaces), so there is hopefully no + # correctness risk, but they need to be able to successfully + # find libpython.so in order to load the module. To allow such + # extensions to load, we set an rpath to point at our lib + # directory, so that if anyone ever tries to find a libpython, + # they successfully find one. See + # https://github.com/astral-sh/python-build-standalone/issues/619 + # for some reports of extensions that need this workaround. + # + # Note that this matches the behavior of Debian/Ubuntu/etc.'s + # interpreter (if package libpython3.x is installed, which it + # usually is thanks to gdb, vim, etc.), because libpython is in + # the system lib directory, as well as the behavior in practice + # on conda-forge miniconda and probably other Conda-family + # Python distributions, which too set an rpath. + # + # There is a downside of making this libpython locatable: some user + # code might do e.g. + # ctypes.CDLL(f"libpython3.{sys.version_info.minor}.so.1.0") + # to get at things in the CPython API not exposed to pure + # Python. This code may _silently misbehave_ on a + # static-libpython interpreter, because you are actually using + # the second copy of libpython. For loading static data or using + # accessors, you might get lucky and things will work, with the + # full set of dangers of C undefined behavior being possible. + # However, there are a few reasons we think this risk is + # tolerable. First, we can't actually fix it by not setting the + # rpath - user code may well find a system libpython3.x.so or + # something which is even more likely to break. Second, this + # exact problem happens with Debian, Conda, etc., so it is very + # unlikely (compared to the extension modules case above) that + # any widely-used code has this problem; the risk is largely + # backwards incompatibility of our own builds. Also, it's quite + # easy for users to fix: simply do + # ctypes.CDLL(None) + # (i.e., dlopen(NULL)), to use symbols already in the process; + # this will work reliably on all interpreters regardless of + # whether they statically or dynamically link libpython. Finally, + # we can (and should, at some point) add a warning, error, or + # silent fix to ctypes for user code that does this, which will + # also cover the case of other libpython3.x.so files on the + # library search path that we cannot suppress. + # + # In the past, when we dynamically linked libpython, we avoided + # using an rpath and instead used a DT_NEEDED entry with + # $ORIGIN/../lib/libpython.so, because LD_LIBRARY_PATH takes + # precedence over DT_RUNPATH, and it's not uncommon to have an + # LD_LIBRARY_PATH that points to some sort of unwanted libpython + # (e.g., actions/setup-python does this as of May 2025). + # Now, though, because we're not actually using code from the + # libpython that's loaded and just need _any_ file of that name + # to satisfy the link, that's not a problem. (This also implies + # another approach to the problem: ensure that libraries find an + # empty dummy libpython.so, which allows the link to succeed but + # ensures they do not use any unwanted symbols. That might be + # worth doing at some point.) + patchelf --force-rpath --set-rpath "\$ORIGIN/../lib" \ + ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION} + + if [ -n "${PYTHON_BINARY_SUFFIX}" ]; then + patchelf --force-rpath --set-rpath "\$ORIGIN/../lib" \ + ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX} + fi + # For libpython3.so (the ABI3 library for embedders), we do + # still dynamically link libpython3.x.so.1.0 (the + # version-specific library), because there is no particular + # speedup/benefit in statically linking libpython into + # libpython3.so, and we'd just be shipping a third copy of the + # libpython code. Therefore we use the old logic for that and + # set an $ORIGIN-relative DT_NEEDED, at least for glibc. + # Unfortunately, musl does not (as of May 2025) support $ORIGIN + # in DT_NEEDED, only in DT_RUNPATH/RPATH, so we did set an rpath + # for bin/python3, and still do for libpython3.so. In both + # cases, we have no concerns/need no workarounds for code + # referencing libpython3.x.so.1.0, because we are actually + # dynamically linking it and so all code will get the real + # libpython3.x.so.1.0 that they want (and it's fine to use + # DT_RUNPATH instead of DT_RPATH). + if [ "${CC}" == "musl-clang" ]; then # libpython3.so isn't present in debug builds. if [ -z "${CPYTHON_DEBUG}" ]; then patchelf --set-rpath "\$ORIGIN/../lib" \ ${ROOT}/out/python/install/lib/libpython3.so fi - - if [ -n "${PYTHON_BINARY_SUFFIX}" ]; then - patchelf --set-rpath "\$ORIGIN/../lib" \ - ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX} - fi else - # If we simply set DT_RUNPATH via --set-rpath, LD_LIBRARY_PATH would be used before - # DT_RUNPATH, which could result in confusion at run-time. But if DT_NEEDED contains a - # slash, the explicit path is used. - patchelf --replace-needed ${LIBPYTHON_SHARED_LIBRARY_BASENAME} "\$ORIGIN/../lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}" \ - ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION} - # libpython3.so isn't present in debug builds. if [ -z "${CPYTHON_DEBUG}" ]; then patchelf --replace-needed ${LIBPYTHON_SHARED_LIBRARY_BASENAME} "\$ORIGIN/../lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}" \ ${ROOT}/out/python/install/lib/libpython3.so fi - - if [ -n "${PYTHON_BINARY_SUFFIX}" ]; then - patchelf --replace-needed ${LIBPYTHON_SHARED_LIBRARY_BASENAME} "\$ORIGIN/../lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}" \ - ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX} - fi fi fi fi @@ -966,9 +1097,6 @@ armv7-unknown-linux-gnueabi) armv7-unknown-linux-gnueabihf) PYTHON_ARCH="arm-linux-gnueabihf" ;; -i686-unknown-linux-gnu) - PYTHON_ARCH="i386-linux-gnu" - ;; mips-unknown-linux-gnu) PYTHON_ARCH="mips-linux-gnu" ;; @@ -1111,7 +1239,7 @@ cp -av ${TOOLS_PATH}/deps/lib/*.a ${ROOT}/out/python/build/lib/ # # We copy the libclang_rt..a library from our clang into the # distribution so it is available. See documentation in quirks.rst for more. -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then cp -av $(dirname $(which clang))/../lib/clang/*/lib/darwin/libclang_rt.osx.a ${ROOT}/out/python/build/lib/ fi @@ -1126,7 +1254,7 @@ if [ -d "${TOOLS_PATH}/deps/lib/tcl8" ]; then cp -av $source ${ROOT}/out/python/install/lib/ done - if [ "${PYBUILD_PLATFORM}" != "macos" ]; then + if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then cp -av ${TOOLS_PATH}/deps/lib/Tix8.4.3 ${ROOT}/out/python/install/lib/ fi fi diff --git a/cpython-unix/build-inputproto.sh b/cpython-unix/build-inputproto.sh deleted file mode 100755 index 9ab52363..00000000 --- a/cpython-unix/build-inputproto.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -set -ex - -ROOT=`pwd` - -pkg-config --version - -export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH -export PKG_CONFIG_PATH=/tools/deps/share/pkgconfig - -tar -xf inputproto-${INPUTPROTO_VERSION}.tar.gz -pushd inputproto-${INPUTPROTO_VERSION} - -CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure \ - --build=${BUILD_TRIPLE} \ - --host=${TARGET_TRIPLE} \ - --prefix=/tools/deps - -make -j `nproc` -make -j `nproc` install DESTDIR=${ROOT}/out diff --git a/cpython-unix/build-kbproto.sh b/cpython-unix/build-kbproto.sh deleted file mode 100755 index 031493e8..00000000 --- a/cpython-unix/build-kbproto.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -set -ex - -ROOT=`pwd` - -pkg-config --version - -export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH -export PKG_CONFIG_PATH=/tools/deps/share/pkgconfig - -tar -xf kbproto-${KBPROTO_VERSION}.tar.gz -pushd kbproto-${KBPROTO_VERSION} - -CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure \ - --build=${BUILD_TRIPLE} \ - --host=${TARGET_TRIPLE} \ - --prefix=/tools/deps - -make -j `nproc` -make -j `nproc` install DESTDIR=${ROOT}/out diff --git a/cpython-unix/build-libX11.sh b/cpython-unix/build-libX11.sh index e8f65ad4..bb45028b 100755 --- a/cpython-unix/build-libX11.sh +++ b/cpython-unix/build-libX11.sh @@ -54,9 +54,6 @@ if [ -n "${CROSS_COMPILING}" ]; then armv7-unknown-linux-gnueabihf) EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" ;; - i686-unknown-linux-gnu) - EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" - ;; mips-unknown-linux-gnu) EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" ;; @@ -81,9 +78,6 @@ if [ -n "${CROSS_COMPILING}" ]; then aarch64-unknown-linux-musl) EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" ;; - i686-unknown-linux-musl) - EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" - ;; mips-unknown-linux-musl) EXTRA_FLAGS="${EXTRA_FLAGS} --enable-malloc0returnsnull" ;; diff --git a/cpython-unix/build-libedit.sh b/cpython-unix/build-libedit.sh index 08387ece..61220593 100755 --- a/cpython-unix/build-libedit.sh +++ b/cpython-unix/build-libedit.sh @@ -82,6 +82,32 @@ index 614795f..4671f1b 100755 fi EOF +# When libedit receives a signal, it re-broadcasts it to its entire pgroup. +# This seems intended to preserve normal ^C behavior in "raw" mode when the +# terminal's ISIG flag is cleared? However, libedit does not in fact clear +# ISIG. (And Jack can't find any evidence of any version that ever did.) This +# sometimes results in the parent process receiving ^C twice back-to-back, +# depending on the vagaries of signal coalescing. More pathologically, if the +# parent tries to signal the child directly with e.g. `kill(pid, SIGTERM)`, +# libedit *signals the parent right back* (not to mention any other pgroup +# siblings or grandparents). This is just wild behavior, even though it's +# probably rare that it matters in practice. Patch it out. See also: +# https://github.com/astral-sh/uv/issues/13919#issuecomment-2960501229. +patch -p1 << "EOF" +diff --git i/src/sig.c w/src/sig.c +index d2b77e7..884b2dd 100644 +--- i/src/sig.c ++++ w/src/sig.c +@@ -107,7 +107,7 @@ sig_handler(int signo) + sel->el_signal->sig_action[i].sa_flags = 0; + sigemptyset(&sel->el_signal->sig_action[i].sa_mask); + (void) sigprocmask(SIG_SETMASK, &oset, NULL); +- (void) kill(0, signo); ++ (void) raise(signo); + errno = save_errno; + } +EOF + cflags="${EXTRA_TARGET_CFLAGS} -fPIC -I${TOOLS_PATH}/deps/include -I${TOOLS_PATH}/deps/include/ncursesw" ldflags="${EXTRA_TARGET_LDFLAGS} -L${TOOLS_PATH}/deps/lib" diff --git a/cpython-unix/build-main.py b/cpython-unix/build-main.py index 6bf91b49..7a7d08b1 100755 --- a/cpython-unix/build-main.py +++ b/cpython-unix/build-main.py @@ -7,7 +7,6 @@ import multiprocessing import os import pathlib -import platform import subprocess import sys @@ -15,6 +14,8 @@ from pythonbuild.downloads import DOWNLOADS from pythonbuild.utils import ( compress_python_archive, + current_host_platform, + default_target_triple, get_target_settings, release_tag_from_git, supported_targets, @@ -28,29 +29,14 @@ def main(): - if sys.platform == "linux": - host_platform = "linux64" - default_target_triple = "x86_64-unknown-linux-gnu" - elif sys.platform == "darwin": - host_platform = "macos" - machine = platform.machine() - - if machine == "arm64": - default_target_triple = "aarch64-apple-darwin" - elif machine == "x86_64": - default_target_triple = "x86_64-apple-darwin" - else: - raise Exception("unhandled macOS machine value: %s" % machine) - else: - print("Unsupported build platform: %s" % sys.platform) - return 1 + host_platform = current_host_platform() # Note these arguments must be synced with `build.py` parser = argparse.ArgumentParser() parser.add_argument( "--target-triple", - default=default_target_triple, + default=default_target_triple(), choices=supported_targets(TARGETS_CONFIG), help="Target host triple to build for", ) @@ -109,6 +95,7 @@ def main(): "toolchain-image-build", "toolchain-image-build.cross", "toolchain-image-build.cross-riscv64", + "toolchain-image-build.debian9", "toolchain-image-gcc", "toolchain-image-xcb", "toolchain-image-xcb.cross", diff --git a/cpython-unix/build-ncurses.sh b/cpython-unix/build-ncurses.sh index b1a568bc..25df7e22 100755 --- a/cpython-unix/build-ncurses.sh +++ b/cpython-unix/build-ncurses.sh @@ -16,7 +16,7 @@ tar -xf ncurses-${NCURSES_VERSION}.tar.gz # ncurses version. Our workaround is to build ncurses for the host when # cross-compiling then make its `tic` available to the target ncurses # build. -if [[ -n "${CROSS_COMPILING}" && "${PYBUILD_PLATFORM}" != "macos" ]]; then +if [[ -n "${CROSS_COMPILING}" && "${PYBUILD_PLATFORM}" != macos* ]]; then echo "building host ncurses to provide modern tic for cross-compile" pushd ncurses-${NCURSES_VERSION} @@ -65,7 +65,7 @@ CONFIGURE_FLAGS=" # ncurses wants --with-build-cc when cross-compiling. But it insists on CC # and this value not being equal, even though using the same binary with # different compiler flags is doable! -if [[ -n "${CROSS_COMPILING}" && "${PYBUILD_PLATFORM}" != "macos" ]]; then +if [[ -n "${CROSS_COMPILING}" && "${PYBUILD_PLATFORM}" != macos* ]]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --with-build-cc=$(which "${HOST_CC}")" fi @@ -91,7 +91,7 @@ fi # binary. So we provide a suitable runtime value and then move files at install # time. -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --datadir=/usr/share --sysconfdir=/etc diff --git a/cpython-unix/build-tix.sh b/cpython-unix/build-tix.sh index a894f528..c1d5fae3 100755 --- a/cpython-unix/build-tix.sh +++ b/cpython-unix/build-tix.sh @@ -28,7 +28,7 @@ if [ "${CC}" = "clang" ]; then CFLAGS="${CFLAGS} -Wno-error=implicit-function-declaration -Wno-error=incompatible-function-pointer-types" fi -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then CFLAGS="${CFLAGS} -I${TOOLS_PATH}/deps/include" EXTRA_CONFIGURE_FLAGS="--without-x" else diff --git a/cpython-unix/build-tk.sh b/cpython-unix/build-tk.sh index 0dca3516..2769a631 100755 --- a/cpython-unix/build-tk.sh +++ b/cpython-unix/build-tk.sh @@ -17,7 +17,7 @@ pushd tk*/unix CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" -if [ "${PYBUILD_PLATFORM}" = "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then CFLAGS="${CFLAGS} -I${TOOLS_PATH}/deps/include -Wno-availability" CFLAGS="${CFLAGS} -Wno-deprecated-declarations -Wno-unknown-attributes -Wno-typedef-redefinition" LDFLAGS="-L${TOOLS_PATH}/deps/lib" @@ -36,7 +36,7 @@ CFLAGS="${CFLAGS}" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" ./configure \ ${EXTRA_CONFIGURE_FLAGS} # Remove wish, since we don't need it. -if [ "${PYBUILD_PLATFORM}" != "macos" ]; then +if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then sed -i 's/all: binaries libraries doc/all: libraries/' Makefile sed -i 's/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE) ${WISH_EXE}/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE)/' Makefile fi diff --git a/cpython-unix/build-xcb-proto.sh b/cpython-unix/build-xcb-proto.sh index 21e8c2e4..5ac092a2 100755 --- a/cpython-unix/build-xcb-proto.sh +++ b/cpython-unix/build-xcb-proto.sh @@ -12,7 +12,7 @@ pkg-config --version export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH export PKG_CONFIG_PATH=/tools/deps/share/pkgconfig -tar -xf xcb-proto-${XCB_PROTO_VERSION}.tar.gz +tar -xf xcb-proto-${XCB_PROTO_VERSION}.tar.xz pushd xcb-proto-${XCB_PROTO_VERSION} CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure \ diff --git a/cpython-unix/build-xextproto.sh b/cpython-unix/build-xextproto.sh deleted file mode 100755 index 090e3f0e..00000000 --- a/cpython-unix/build-xextproto.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -set -ex - -ROOT=`pwd` - -pkg-config --version - -export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH -export PKG_CONFIG_PATH=/tools/deps/share/pkgconfig - -tar -xf xextproto-${XEXTPROTO_VERSION}.tar.gz -pushd xextproto-${XEXTPROTO_VERSION} - -EXTRA_CONFIGURE_FLAGS= -if [ -n "${CROSS_COMPILING}" ]; then - if echo "${TARGET_TRIPLE}" | grep -q -- "-unknown-linux-musl"; then - # xextproto does not support configuration of musl targets so we pretend the target matches the - # build triple and enable cross-compilation manually - TARGET_TRIPLE="$(echo "${TARGET_TRIPLE}" | sed -e 's/-unknown-linux-musl/-unknown-linux-gnu/g')" - EXTRA_CONFIGURE_FLAGS="cross_compiling=yes" - fi -fi - -CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure \ - --build=${BUILD_TRIPLE} \ - --host=${TARGET_TRIPLE} \ - --prefix=/tools/deps \ - ${EXTRA_CONFIGURE_FLAGS} - -make -j `nproc` -make -j `nproc` install DESTDIR=${ROOT}/out diff --git a/cpython-unix/build-xproto.sh b/cpython-unix/build-xproto.sh deleted file mode 100755 index 6f3d2b6b..00000000 --- a/cpython-unix/build-xproto.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -set -ex - -ROOT=`pwd` - -pkg-config --version - -export PATH=${TOOLS_PATH}/${TOOLCHAIN}/bin:${TOOLS_PATH}/host/bin:$PATH -export PKG_CONFIG_PATH=${TOOLS_PATH}/deps/share/pkgconfig - -tar -xf xproto-${XPROTO_VERSION}.tar.gz -pushd xproto-${XPROTO_VERSION} - -EXTRA_CONFIGURE_FLAGS= -if [ -n "${CROSS_COMPILING}" ]; then - if echo "${TARGET_TRIPLE}" | grep -q -- "-unknown-linux-musl"; then - # xproto does not support configuration of musl targets so we pretend the target matches the - # build triple and enable cross-compilation manually - TARGET_TRIPLE="$(echo "${TARGET_TRIPLE}" | sed -e 's/-unknown-linux-musl/-unknown-linux-gnu/g')" - EXTRA_CONFIGURE_FLAGS="cross_compiling=yes" - fi -fi - -CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure \ - --build=${BUILD_TRIPLE} \ - --host=${TARGET_TRIPLE} \ - --prefix=/tools/deps \ - ${EXTRA_CONFIGURE_FLAGS} - -make -j ${NUM_CPUS} -make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out diff --git a/cpython-unix/build.Dockerfile b/cpython-unix/build.Dockerfile index 09e37fab..e44d0a2e 100644 --- a/cpython-unix/build.Dockerfile +++ b/cpython-unix/build.Dockerfile @@ -1,8 +1,5 @@ {% include 'base.Dockerfile' %} -# libc6-dev:i386 pulls in 32-bit system libraries to enable cross-compiling -# to i386. -# # libffi-dev and zlib1g-dev are present so host Python (during cross-builds) # can build the ctypes and zlib extensions. So comment in build-cpython.sh # for more context. @@ -14,7 +11,6 @@ RUN ulimit -n 10000 && apt-get install \ bzip2 \ file \ libc6-dev \ - libc6-dev:i386 \ libffi-dev \ make \ patch \ diff --git a/cpython-unix/build.debian9.Dockerfile b/cpython-unix/build.debian9.Dockerfile new file mode 100644 index 00000000..1f7c91b6 --- /dev/null +++ b/cpython-unix/build.debian9.Dockerfile @@ -0,0 +1,16 @@ +{% include 'base.debian9.Dockerfile' %} + +RUN ulimit -n 10000 && apt-get install \ + bzip2 \ + file \ + libc6-dev \ + libffi-dev \ + make \ + patch \ + perl \ + pkg-config \ + tar \ + xz-utils \ + unzip \ + zip \ + zlib1g-dev diff --git a/cpython-unix/build.py b/cpython-unix/build.py index c90f7deb..01d39b2a 100755 --- a/cpython-unix/build.py +++ b/cpython-unix/build.py @@ -64,34 +64,6 @@ MACOS_ALLOW_FRAMEWORKS = {"CoreFoundation"} -def install_sccache(build_env): - """Attempt to install sccache into the build environment. - - This will attempt to locate a sccache executable and copy it - into the root directory of the build environment. - """ - candidates = [ - # Prefer a binary in the project itself. - ROOT / "sccache", - ] - - # Look for sccache in $PATH, but only if the build environment - # isn't isolated, as copying binaries into an isolated environment - # may not run. And running sccache in an isolated environment won't - # do anything meaningful unless an external cache is being used. - if not build_env.is_isolated: - for path in os.environ.get("PATH", "").split(":"): - if not path: - continue - - candidates.append(pathlib.Path(path) / "sccache") - - for candidate in candidates: - if candidate.exists(): - build_env.copy_file(candidate) - return - - def add_target_env(env, build_platform, target_triple, build_env): add_env_common(env) @@ -116,14 +88,21 @@ def add_target_env(env, build_platform, target_triple, build_env): extra_host_cflags = [] extra_host_ldflags = [] - if build_platform == "linux64": - env["BUILD_TRIPLE"] = "x86_64-unknown-linux-gnu" + if build_platform.startswith("linux_"): + machine = platform.machine() - env["TARGET_TRIPLE"] = ( - target_triple.replace("x86_64_v2-", "x86_64-") - .replace("x86_64_v3-", "x86_64-") - .replace("x86_64_v4-", "x86_64-") - ) + if machine == "aarch64": + env["BUILD_TRIPLE"] = "aarch64-unknown-linux-gnu" + env["TARGET_TRIPLE"] = target_triple + elif machine == "x86_64": + env["BUILD_TRIPLE"] = "x86_64-unknown-linux-gnu" + env["TARGET_TRIPLE"] = ( + target_triple.replace("x86_64_v2-", "x86_64-") + .replace("x86_64_v3-", "x86_64-") + .replace("x86_64_v4-", "x86_64-") + ) + else: + raise Exception("unhandled Linux machine value: %s" % machine) # This will make x86_64_v2, etc count as cross-compiling. This is # semantically correct, since the current machine may not support @@ -133,7 +112,7 @@ def add_target_env(env, build_platform, target_triple, build_env): ): env["CROSS_COMPILING"] = "1" - if build_platform == "macos": + elif build_platform.startswith("macos_"): machine = platform.machine() if machine == "arm64": @@ -216,6 +195,8 @@ def add_target_env(env, build_platform, target_triple, build_env): extra_host_cflags.extend(["-isysroot", host_sdk_path]) extra_host_ldflags.extend(["-isysroot", host_sdk_path]) + else: + raise Exception("unhandled build platform: %s" % build_platform) env["EXTRA_HOST_CFLAGS"] = " ".join(extra_host_cflags) env["EXTRA_HOST_LDFLAGS"] = " ".join(extra_host_ldflags) @@ -232,7 +213,7 @@ def toolchain_archive_path(package_name, host_platform): def install_binutils(platform): - return platform != "macos" + return not platform.startswith("macos_") def simple_build( @@ -246,6 +227,7 @@ def simple_build( dest_archive, extra_archives=None, tools_path="deps", + python_host_version=None, ): archive = download_entry(entry, DOWNLOADS_PATH) @@ -264,6 +246,15 @@ def simple_build( for a in extra_archives or []: build_env.install_artifact_archive(BUILD, a, target_triple, build_options) + if python_host_version: + majmin = ".".join(python_host_version.split(".")[0:2]) + build_env.install_toolchain_archive( + BUILD, + f"cpython-{majmin}", + host_platform, + version=python_host_version, + ) + build_env.copy_file(archive) build_env.copy_file(SUPPORT / ("build-%s.sh" % entry)) @@ -292,8 +283,6 @@ def build_binutils(client, image, host_platform): archive = download_entry("binutils", DOWNLOADS_PATH) with build_environment(client, image) as build_env: - install_sccache(build_env) - build_env.copy_file(archive) build_env.copy_file(SUPPORT / "build-binutils.sh") @@ -410,7 +399,7 @@ def build_tix( ) depends = {"tcl", "tk"} - if host_platform != "macos": + if not host_platform.startswith("macos_"): depends |= {"libX11", "xorgproto"} for p in sorted(depends): @@ -516,10 +505,14 @@ def python_build_info( binary_suffix = "" - if platform == "linux64": + if platform in ("linux_x86_64", "linux_aarch64"): + arch = platform.removeprefix("linux_") + bi["core"]["static_lib"] = ( - "install/lib/python{version}/config-{version}{binary_suffix}-x86_64-linux-gnu/libpython{version}{binary_suffix}.a".format( - version=version, binary_suffix=binary_suffix + "install/lib/python{version}/config-{version}{binary_suffix}-{arch}-linux-gnu/libpython{version}{binary_suffix}.a".format( + version=version, + binary_suffix=binary_suffix, + arch=arch, ) ) @@ -539,7 +532,7 @@ def python_build_info( object_file_format = f"llvm-bitcode:%{llvm_version}" else: object_file_format = "elf" - elif platform == "macos": + elif platform.startswith("macos_"): bi["core"]["static_lib"] = ( "install/lib/python{version}/config-{version}{binary_suffix}-darwin/libpython{version}{binary_suffix}.a".format( version=version, binary_suffix=binary_suffix @@ -562,6 +555,7 @@ def python_build_info( bi["object_file_format"] = object_file_format # Determine allowed libaries on Linux + libs = extra_metadata["python_config_vars"].get("LIBS", "").split() mips = target_triple.split("-")[0] in {"mips", "mipsel"} linux_allowed_system_libraries = LINUX_ALLOW_SYSTEM_LIBRARIES.copy() if mips and version == "3.13": @@ -569,14 +563,26 @@ def python_build_info( linux_allowed_system_libraries.add("atomic") riscv = target_triple.split("-")[0] in {"riscv64"} if riscv: - # RISC-V binary often comes with libatomic on old GCC versions + # On older GCC versions, RISC-V sub-word atomic operations require a + # helper function found in libatomic. To facilitate this, GCC <15 adds + # "-latomic" to the definition of "-pthread". We think it's generally + # reasonable on RISC-V systems (but not all Linux systems in general) + # to expect a libatomic system library is installed. + # + # Because "-latomic" is implicitly added by "-pthread", it may not be + # found in the LIBS sysconfig variable, but we need to pretend it is so + # that it gets into PYTHON.json (in particular, so that the validation + # script accepts this dependency). + # # See https://github.com/riscvarchive/riscv-gcc/issues/12 # https://github.com/riscvarchive/riscv-gcc/issues/337 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005 + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104338 + # https://github.com/gcc-mirror/gcc/commit/203f3060dd363361b172f7295f42bb6bf5ac0b3b linux_allowed_system_libraries.add("atomic") + libs.append("-latomic") # Add in core linking annotations. - libs = extra_metadata["python_config_vars"].get("LIBS", "").split() skip = False for i, lib in enumerate(libs): if skip: @@ -586,9 +592,15 @@ def python_build_info( if lib.startswith("-l"): lib = lib[2:] - if platform == "linux64" and lib not in linux_allowed_system_libraries: + if ( + platform in ("linux_x86_64", "linux_aarch64") + and lib not in linux_allowed_system_libraries + ): raise Exception("unexpected library in LIBS (%s): %s" % (libs, lib)) - elif platform == "macos" and lib not in MACOS_ALLOW_SYSTEM_LIBRARIES: + elif ( + platform.startswith("macos_") + and lib not in MACOS_ALLOW_SYSTEM_LIBRARIES + ): raise Exception("unexpected library in LIBS (%s): %s" % (libs, lib)) log("adding core system link library: %s" % lib) @@ -780,6 +792,7 @@ def build_cpython( for p in sorted(packages): build_env.install_artifact_archive(BUILD, p, target_triple, build_options) + # Install the host CPython. build_env.install_toolchain_archive( BUILD, entry_name, host_platform, version=python_version ) @@ -854,7 +867,7 @@ def build_cpython( extension_module_loading = ["builtin"] crt_features = [] - if host_platform == "linux64": + if host_platform in ("linux_x86_64", "linux_aarch64"): if "static" in parsed_build_options: crt_features.append("static") else: @@ -880,7 +893,7 @@ def build_cpython( python_symbol_visibility = "global-default" - elif host_platform == "macos": + elif host_platform.startswith("macos_"): python_symbol_visibility = "global-default" extension_module_loading.append("shared-library") crt_features.append("libSystem") @@ -1016,6 +1029,11 @@ def main(): default=None, help="A custom path to CPython source files to use", ) + parser.add_argument( + "--python-host-version", + default=None, + help="Python X.Y version for host Python installation", + ) parser.add_argument("action") args = parser.parse_args() @@ -1031,6 +1049,8 @@ def main(): dest_archive = pathlib.Path(args.dest_archive) docker_image = args.docker_image + python_host_version = args.python_host_version + settings = get_target_settings(TARGETS_CONFIG, target_triple) if args.action == "dockerfiles": @@ -1076,10 +1096,14 @@ def main(): with image_path.open("rb") as fh: image_data = fh.read() - build_docker_image(client, image_data, BUILD, image_name) + build_docker_image(client, image_data, BUILD, image_name, host_platform) elif action == "binutils": - build_binutils(client, get_image(client, ROOT, BUILD, "gcc"), host_platform) + build_binutils( + client, + get_image(client, ROOT, BUILD, docker_image, host_platform), + host_platform, + ) elif action == "clang": materialize_clang(host_platform, target_triple) @@ -1087,7 +1111,7 @@ def main(): elif action == "musl": build_musl( client, - get_image(client, ROOT, BUILD, "gcc"), + get_image(client, ROOT, BUILD, docker_image, host_platform), host_platform, target_triple, build_options, @@ -1097,7 +1121,7 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, @@ -1111,7 +1135,7 @@ def main(): build_libedit( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), host_platform=host_platform, target_triple=target_triple, build_options=build_options, @@ -1122,8 +1146,6 @@ def main(): "bdb", "bzip2", "expat", - "inputproto", - "kbproto", "libffi-3.3", "libffi", "libpthread-stubs", @@ -1137,9 +1159,7 @@ def main(): "tcl", "uuid", "x11-util-macros", - "xextproto", "xorgproto", - "xproto", "xtrans", "xz", "zlib", @@ -1149,7 +1169,7 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, @@ -1162,22 +1182,18 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, build_options=build_options, dest_archive=dest_archive, extra_archives={ - "inputproto", - "kbproto", "libpthread-stubs", "libXau", "libxcb", "x11-util-macros", - "xextproto", "xorgproto", - "xproto", "xtrans", }, ) @@ -1186,45 +1202,47 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, build_options=build_options, dest_archive=dest_archive, - extra_archives={"x11-util-macros", "xproto"}, + extra_archives={"x11-util-macros", "xorgproto"}, ) elif action == "xcb-proto": simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, build_options=build_options, dest_archive=dest_archive, + python_host_version=python_host_version, ) elif action == "libxcb": simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, build_options=build_options, dest_archive=dest_archive, - extra_archives={"libpthread-stubs", "libXau", "xcb-proto", "xproto"}, + extra_archives={"libpthread-stubs", "libXau", "xcb-proto", "xorgproto"}, + python_host_version=python_host_version, ) elif action == "tix": build_tix( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), host_platform=host_platform, target_triple=target_triple, build_options=build_options, @@ -1233,7 +1251,7 @@ def main(): elif action == "tk": extra_archives = {"tcl"} - if host_platform != "macos": + if not host_platform.startswith("macos_"): extra_archives |= { "libX11", "libXau", @@ -1245,19 +1263,20 @@ def main(): simple_build( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action, host_platform=host_platform, target_triple=target_triple, build_options=build_options, dest_archive=dest_archive, extra_archives=extra_archives, + python_host_version=python_host_version, ) elif action.startswith("cpython-") and action.endswith("-host"): build_cpython_host( client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), action[:-5], host_platform=host_platform, target_triple=target_triple, @@ -1276,7 +1295,7 @@ def main(): build_cpython( settings, client, - get_image(client, ROOT, BUILD, docker_image), + get_image(client, ROOT, BUILD, docker_image, host_platform), host_platform=host_platform, target_triple=target_triple, build_options=build_options, diff --git a/cpython-unix/extension-modules.yml b/cpython-unix/extension-modules.yml index a8ff460f..3d69f049 100644 --- a/cpython-unix/extension-modules.yml +++ b/cpython-unix/extension-modules.yml @@ -38,15 +38,12 @@ _blake2: - Modules/_hacl/include - Modules/_hacl/internal minimum-python-version: "3.14" - links-conditional: - - name: :libHacl_Hash_Blake2.a - minimum-python-version: "3.14" defines-conditional: - define: _BSD_SOURCE minimum-python-version: "3.14" - define: _DEFAULT_SOURCE minimum-python-version: "3.14" - # Disable `explicit_bzero`, it requires glib 2.25+ + # Disable `explicit_bzero`, it requires glibc 2.25+ - define: LINUX_NO_EXPLICIT_BZERO minimum-python-version: "3.14" @@ -91,6 +88,9 @@ _collections: _contextvars: sources: - _contextvarsmodule.c + config-c-only-conditional: + - config-c-only: true + minimum-python-version: "3.14" _crypt: maximum-python-version: "3.12" @@ -252,7 +252,6 @@ _decimal: - define: CONFIG_32=1 targets: - armv7-.* - - i686-.* - mips-.* - mipsel-.* - define: CONFIG_64=1 @@ -302,7 +301,6 @@ _hashlib: # a static library so there isn't a runtime dependency. - name: ':libatomic.a' targets: - - i686-unknown-linux-gnu - mips-unknown-linux-gnu - mipsel-unknown-linux-gnu - x86_64.*-unknown-linux-gnu @@ -311,6 +309,19 @@ _heapq: sources: - _heapqmodule.c +_hmac: + minimum-python-version: '3.14' + sources: + - hmacmodule.c + - _hacl/Hacl_HMAC.c + - _hacl/Hacl_Streaming_HMAC.c + includes: + - Modules/_hacl/ + - Modules/_hacl/include/ + defines: + - _BSD_SOURCE + - _DEFAULT_SOURCE + _imp: config-c-only: true @@ -420,6 +431,12 @@ _random: sources: - _randommodule.c + +_remote_debugging: + minimum-python-version: "3.14" + sources: + - _remote_debugging_module.c + _scproxy: # _scproxy is Apple OS only. # APIs required by _scproxy not available on iOS. @@ -457,7 +474,8 @@ _sha2: minimum-python-version: "3.12" sources: - sha2module.c - - _hacl/Hacl_Hash_SHA2.c + sources-conditional: + - source: _hacl/Hacl_Hash_SHA2.c includes: - Modules/_hacl/include defines: @@ -471,7 +489,6 @@ _sha3: maximum-python-version: "3.11" - source: sha3module.c minimum-python-version: "3.12" - - source: _hacl/Hacl_Hash_SHA3.c minimum-python-version: "3.12" includes: @@ -550,7 +567,6 @@ _ssl: # a static library so there isn't a runtime dependency. - name: ':libatomic.a' targets: - - i686-unknown-linux-gnu - mips-unknown-linux-gnu - mipsel-unknown-linux-gnu - x86_64.*-unknown-linux-gnu @@ -600,6 +616,7 @@ _testcapi: _testexternalinspection: minimum-python-version: '3.13' + maximum-python-version: '3.13' sources: - _testexternalinspection.c @@ -628,6 +645,8 @@ _testinternalcapi: minimum-python-version: "3.13" - source: _testinternalcapi/test_lock.c minimum-python-version: "3.13" + - source: _testinternalcapi/complex.c + minimum-python-version: "3.14" _testmultiphase: minimum-python-version: '3.9' @@ -700,6 +719,12 @@ _tracemalloc: required-targets: - .* +_types: + minimum-python-version: "3.14" + setup-enabled: true + sources: + - _typesmodule.c + _typing: minimum-python-version: "3.11" setup-enabled-conditional: @@ -746,6 +771,17 @@ _xxtestfuzz: - _xxtestfuzz/_xxtestfuzz.c - _xxtestfuzz/fuzzer.c +_zstd: + # Disable on all targets until we add a zstd library + disabled-targets: + - .* + minimum-python-version: '3.14' + sources: + - _zstd/_zstdmodule.c + - _zstd/zdict.c + - _zstd/compressor.c + - _zstd/decompressor.c + _zoneinfo: minimum-python-version: "3.9" sources: diff --git a/cpython-unix/gcc.debian9.Dockerfile b/cpython-unix/gcc.debian9.Dockerfile new file mode 100644 index 00000000..92d764e8 --- /dev/null +++ b/cpython-unix/gcc.debian9.Dockerfile @@ -0,0 +1,14 @@ +{% include 'base.debian9.Dockerfile' %} +RUN ulimit -n 10000 && apt-get install \ + autoconf \ + automake \ + bison \ + build-essential \ + gawk \ + gcc \ + libtool \ + make \ + tar \ + texinfo \ + xz-utils \ + unzip diff --git a/cpython-unix/patch-configure-bolt-apply-flags-128514.patch b/cpython-unix/patch-configure-bolt-apply-flags-128514.patch index e810a482..e9d86432 100644 --- a/cpython-unix/patch-configure-bolt-apply-flags-128514.patch +++ b/cpython-unix/patch-configure-bolt-apply-flags-128514.patch @@ -12,11 +12,3 @@ index ee034e5a962..f1a69b7d4a7 100644 -icf=1 -inline-all -split-eh -@@ -2196,6 +2197,7 @@ then - -dyno-stats - -use-gnu-stack - -frame-opt=hot -+ -hugify - ")] - ) - fi diff --git a/cpython-unix/patch-configure-bolt-icf-safe.patch b/cpython-unix/patch-configure-bolt-icf-safe.patch new file mode 100644 index 00000000..1cc41adc --- /dev/null +++ b/cpython-unix/patch-configure-bolt-icf-safe.patch @@ -0,0 +1,84 @@ +From 91fc5ae4a5a66a03931f8cd383abd2aa062bb0e9 Mon Sep 17 00:00:00 2001 +From: Geoffrey Thomas +Date: Sat, 24 May 2025 19:04:09 -0400 +Subject: [PATCH 1/1] Use only safe identical code folding with BOLT + +"Identical code folding" (ICF) is the feature of an optimizer to find that two +functions have the same code and that they can therefore be deduplicated +in the binary. While this is usually safe, it can cause observable +behavior differences if the program relies on the fact that the two +functions have different addresses. + +CPython relies on this in (at least) Objects/typeobject.c, which defines +two functions wrap_binaryfunc() and wrap_binaryfunc_l() with the same +implementation, and stores their addresses in the slotdefs array. If +these two functions have the same address, update_one_slot() in that +file will fill in slots it shouldn't, causing, for instances, +classes defined in Python that inherit from some built-in types to +misbehave. + +As of LLVM 20 (llvm/llvm-project#116275), BOLT has a "safe ICF" mode, +where it looks to see if there are any uses of a function symbol outside +function calls (e.g., relocations in data sections) and skips ICF on +such functions. The intent is that this avoids observable behavior +differences but still saves storage as much as possible. + +This version is about two months old at the time of writing. To support +older LLVM versions, we have to turn off ICF entirely. + +This problem was previously noticed for Windows/MSVC in #53093 (and +again in #24098), where the default behavior of PGO is to enable ICF +(which they expand to "identical COMDAT folding") and we had to turn it +off. +--- + configure | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- + configure.ac | 25 ++++++++++++++++++++++++- + 2 files changed, 73 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 8d939f07505..25737e3f9d6 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2129,6 +2129,29 @@ if test "$Py_BOLT" = 'true' ; then + else + AC_MSG_ERROR([merge-fdata is required for a --enable-bolt build but could not be found.]) + fi ++ ++ py_bolt_icf_flag="-icf=safe" ++ AC_CACHE_CHECK( ++ [whether ${LLVM_BOLT} supports safe identical code folding], ++ [py_cv_bolt_icf_safe], ++ [ ++ saved_cflags="$CFLAGS" ++ saved_ldflags="$LDFLAGS" ++ CFLAGS="$CFLAGS_NODIST" ++ LDFLAGS="$LDFLAGS_NODIST" ++ AC_LINK_IFELSE( ++ [AC_LANG_PROGRAM([[]], [[]])], ++ [py_cv_bolt_icf_safe=no ++ ${LLVM_BOLT} -icf=safe -o conftest.bolt conftest$EXEEXT >&AS_MESSAGE_LOG_FD 2>&1 dnl ++ && py_cv_bolt_icf_safe=yes], ++ [AC_MSG_FAILURE([could not compile empty test program])]) ++ CFLAGS="$saved_cflags" ++ LDFLAGS="$saved_ldflags" ++ ] ++ ) ++ if test "$py_cv_bolt_icf_safe" = no; then ++ py_bolt_icf_flag="" ++ fi + fi + + dnl Enable BOLT of libpython if built. +@@ -2184,7 +2207,7 @@ then + -reorder-blocks=ext-tsp + -reorder-functions=cdsort + -split-functions + -split-strategy=cdsplit +- -icf=1 ++ ${py_bolt_icf_flag} + -inline-all + -split-eh + -reorder-functions-use-hot-size +-- +2.39.5 (Apple Git-154) + diff --git a/cpython-unix/patch-force-cross-compile.patch b/cpython-unix/patch-force-cross-compile.patch deleted file mode 100644 index 35f2c6db..00000000 --- a/cpython-unix/patch-force-cross-compile.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/configure b/configure -index d078887b2f..8f1ea07cd8 100755 ---- a/configure -+++ b/configure -@@ -1329,14 +1329,7 @@ build=$build_alias - host=$host_alias - target=$target_alias - --# FIXME: To remove some day. --if test "x$host_alias" != x; then -- if test "x$build_alias" = x; then -- cross_compiling=maybe -- elif test "x$build_alias" != "x$host_alias"; then -- cross_compiling=yes -- fi --fi -+cross_compiling=yes - - ac_tool_prefix= - test -n "$host_alias" && ac_tool_prefix=$host_alias- diff --git a/cpython-unix/patch-jit-cflags-313.patch b/cpython-unix/patch-jit-cflags-313.patch new file mode 100644 index 00000000..d82d1eed --- /dev/null +++ b/cpython-unix/patch-jit-cflags-313.patch @@ -0,0 +1,80 @@ +diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py +index 50b5d923a35..4a71476026f 100644 +--- a/Tools/jit/_targets.py ++++ b/Tools/jit/_targets.py +@@ -10,6 +10,7 @@ + import sys + import tempfile + import typing ++import shlex + + import _llvm + import _schema +@@ -44,6 +45,17 @@ class _Target(typing.Generic[_S, _R]): + stable: bool = False + debug: bool = False + verbose: bool = False ++ cflags: str = "" ++ known_symbols: dict[str, int] = dataclasses.field(default_factory=dict) ++ ++ def _get_nop(self) -> bytes: ++ if re.fullmatch(r"aarch64-.*", self.triple): ++ nop = b"\x1f\x20\x03\xD5" ++ elif re.fullmatch(r"x86_64-.*|i686.*", self.triple): ++ nop = b"\x90" ++ else: ++ raise ValueError(f"NOP not defined for {self.triple}") ++ return nop + + def _compute_digest(self, out: pathlib.Path) -> str: + hasher = hashlib.sha256() +@@ -114,6 +126,7 @@ async def _compile( + return _stencils.StencilGroup() + o = tempdir / f"{opname}.o" + args = [ ++ *shlex.split(self.cflags), + f"--target={self.triple}", + "-DPy_BUILD_CORE_MODULE", + "-D_DEBUG" if self.debug else "-DNDEBUG", +diff --git a/Tools/jit/build.py b/Tools/jit/build.py +index 4a23c6f0afa..618b53804db 100644 +--- a/Tools/jit/build.py ++++ b/Tools/jit/build.py +@@ -22,7 +22,11 @@ + parser.add_argument( + "-v", "--verbose", action="store_true", help="echo commands as they are run" + ) ++ parser.add_argument( ++ "--with-cflags", help="additional flags to pass to the compiler", default="" ++ ) + args = parser.parse_args() + args.target.debug = args.debug + args.target.verbose = args.verbose ++ args.target.cflags = args.with_cflags + args.target.build(pathlib.Path.cwd(), comment=comment, force=args.force) +diff --git a/configure b/configure +index 1cd1f690f7b..7fb6c4adfea 100755 +--- a/configure ++++ b/configure +@@ -8326,7 +8326,7 @@ then : + + else $as_nop + as_fn_append CFLAGS_NODIST " $jit_flags" +- REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host" ++ REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host --with-cflags=\"\$(CONFIGURE_CFLAGS)\"" + JIT_STENCILS_H="jit_stencils.h" + if test "x$Py_DEBUG" = xtrue + then : +diff --git a/configure.ac b/configure.ac +index 3fcb18922c5..616999a96b2 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1846,7 +1846,7 @@ AS_VAR_IF([jit_flags], + [], + [AS_VAR_APPEND([CFLAGS_NODIST], [" $jit_flags"]) + AS_VAR_SET([REGEN_JIT_COMMAND], +- ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host"]) ++ ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host --with-cflags=\"\$(CONFIGURE_CFLAGS)\""]) + AS_VAR_SET([JIT_STENCILS_H], ["jit_stencils.h"]) + AS_VAR_IF([Py_DEBUG], + [true], diff --git a/cpython-unix/patch-jit-cflags-314.patch b/cpython-unix/patch-jit-cflags-314.patch new file mode 100644 index 00000000..a75563b4 --- /dev/null +++ b/cpython-unix/patch-jit-cflags-314.patch @@ -0,0 +1,90 @@ +diff --git a/Misc/NEWS.d/next/Build/2025-05-19-18-09-20.gh-issue-134273.ZAliyy.rst b/Misc/NEWS.d/next/Build/2025-05-19-18-09-20.gh-issue-134273.ZAliyy.rst +new file mode 100644 +index 00000000000..3eb13cefbe6 +--- /dev/null ++++ b/Misc/NEWS.d/next/Build/2025-05-19-18-09-20.gh-issue-134273.ZAliyy.rst +@@ -0,0 +1 @@ ++Add support for configuring compiler flags for the JIT with ``CFLAGS_JIT`` +diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py +index d0a1c081ffe..b383e39da19 100644 +--- a/Tools/jit/_targets.py ++++ b/Tools/jit/_targets.py +@@ -10,6 +10,7 @@ + import sys + import tempfile + import typing ++import shlex + + import _llvm + import _schema +@@ -46,6 +47,7 @@ class _Target(typing.Generic[_S, _R]): + stable: bool = False + debug: bool = False + verbose: bool = False ++ cflags: str = "" + known_symbols: dict[str, int] = dataclasses.field(default_factory=dict) + pyconfig_dir: pathlib.Path = pathlib.Path.cwd().resolve() + +@@ -62,6 +64,7 @@ def _compute_digest(self) -> str: + hasher = hashlib.sha256() + hasher.update(self.triple.encode()) + hasher.update(self.debug.to_bytes()) ++ hasher.update(self.cflags.encode()) + # These dependencies are also reflected in _JITSources in regen.targets: + hasher.update(PYTHON_EXECUTOR_CASES_C_H.read_bytes()) + hasher.update((self.pyconfig_dir / "pyconfig.h").read_bytes()) +@@ -155,6 +158,8 @@ async def _compile( + f"{o}", + f"{c}", + *self.args, ++ # Allow user-provided CFLAGS to override any defaults ++ *shlex.split(self.cflags), + ] + await _llvm.run("clang", args, echo=self.verbose) + return await self._parse(o) +diff --git a/Tools/jit/build.py b/Tools/jit/build.py +index 1afd0c76bad..a0733005929 100644 +--- a/Tools/jit/build.py ++++ b/Tools/jit/build.py +@@ -39,11 +39,15 @@ + parser.add_argument( + "-v", "--verbose", action="store_true", help="echo commands as they are run" + ) ++ parser.add_argument( ++ "--cflags", help="additional flags to pass to the compiler", default="" ++ ) + args = parser.parse_args() + for target in args.target: + target.debug = args.debug + target.force = args.force + target.verbose = args.verbose ++ target.cflags = args.cflags + target.pyconfig_dir = args.pyconfig_dir + target.build( + comment=comment, +diff --git a/configure b/configure +index 029bf527da4..fef9f2d7da9 100755 +--- a/configure ++++ b/configure +@@ -10863,7 +10863,7 @@ then : + + else case e in #( + e) as_fn_append CFLAGS_NODIST " $jit_flags" +- REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir ." ++ REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --cflags=\"$CFLAGS_JIT\"" + JIT_STENCILS_H="jit_stencils.h" + if test "x$Py_DEBUG" = xtrue + then : +diff --git a/configure.ac b/configure.ac +index 371b2e8ed73..cc37a636c52 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2776,7 +2776,7 @@ AS_VAR_IF([jit_flags], + [], + [AS_VAR_APPEND([CFLAGS_NODIST], [" $jit_flags"]) + AS_VAR_SET([REGEN_JIT_COMMAND], +- ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir ."]) ++ ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --cflags=\"$CFLAGS_JIT\""]) + AS_VAR_SET([JIT_STENCILS_H], ["jit_stencils.h"]) + AS_VAR_IF([Py_DEBUG], + [true], diff --git a/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter-3.10.patch b/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter-3.10.patch new file mode 100644 index 00000000..33bd662a --- /dev/null +++ b/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter-3.10.patch @@ -0,0 +1,93 @@ +From 579a7cf9498ccfa656dd720a5db8dd6e04e97150 Mon Sep 17 00:00:00 2001 +From: Geoffrey Thomas +Date: Sat, 19 Apr 2025 11:13:40 -0400 +Subject: [PATCH 1/1] configure: add --enable-static-libpython-for-interpreter + +This option changes the behavior of --enable-shared to continue to build +the libpython3.x.so shared library, but not use it for linking the +python3 interpreter executable. Instead, the executable is linked +directly against the libpython .o files as it would be with +--disable-shared [in newer versions of Python]. + +There are two benefits of this change. First, libpython uses +thread-local storage, which is noticeably slower when used in a loaded +module instead of in the main program, because the main program can take +advantage of constant offsets from the thread state pointer but loaded +modules have to dynamically call a function __tls_get_addr() to +potentially allocate their thread-local storage area. (There is another +thread-local storage model for dynamic libraries which mitigates most of +this performance hit, but it comes at the cost of preventing +dlopen("libpython3.x.so"), which is a use case we want to preserve.) + +Second, this improves the user experience around relocatable Python a +little bit, in that we don't need to use an $ORIGIN-relative path to +locate libpython3.x.so, which has some mild benefits around musl (which +does not support $ORIGIN-relative DT_NEEDED, only $ORIGIN-relative +DT_RPATH/DT_RUNPATH), users who want to make the interpreter setuid or +setcap (which prevents processing $ORIGIN), etc. +--- + Makefile.pre.in | 4 +++- + configure.ac | 18 ++++++++++++++++++ + 2 files changed, 21 insertions(+), 1 deletion(-) + +diff --git a/Makefile.pre.in b/Makefile.pre.in +index fa99dd86c41..84c00a5c071 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -458,6 +458,8 @@ LIBRARY_OBJS= \ + $(LIBRARY_OBJS_OMIT_FROZEN) \ + Python/frozen.o + ++LINK_PYTHON_OBJS=@LINK_PYTHON_OBJS@ ++ + ########################################################################## + # DTrace + +@@ -586,7 +588,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c + + # Build the interpreter + $(BUILDPYTHON): Programs/python.o $(LIBRARY_DEPS) +- $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) ++ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) + + platform: $(BUILDPYTHON) pybuilddir.txt + $(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform +diff --git a/configure.ac b/configure.ac +index ac3be3850a9..a07003a24ed 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1093,6 +1093,17 @@ then + fi + AC_MSG_RESULT($enable_shared) + ++AC_MSG_CHECKING([for --enable-static-libpython-for-interpreter]) ++AC_ARG_ENABLE([static-libpython-for-interpreter], ++ AS_HELP_STRING([--enable-static-libpython-for-interpreter], ++ [even with --enable-shared, statically link libpython into the interpreter (default is to use the shared library)])) ++ ++if test -z "$enable_static_libpython_for_interpreter" ++then ++ enable_static_libpython_for_interpreter="no" ++fi ++AC_MSG_RESULT([$enable_static_libpython_for_interpreter]) ++ + AC_MSG_CHECKING(for --enable-profiling) + AC_ARG_ENABLE(profiling, + AS_HELP_STRING([--enable-profiling], [enable C-level code profiling with gprof (default is no)])) +@@ -1198,6 +1209,13 @@ fi + + AC_MSG_RESULT($LDLIBRARY) + ++if test "$enable_static_libpython_for_interpreter" = "yes"; then ++ LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' ++else ++ LINK_PYTHON_OBJS='$(BLDLIBRARY)' ++fi ++AC_SUBST(LINK_PYTHON_OBJS) ++ + AC_SUBST(AR) + AC_CHECK_TOOLS(AR, ar aal, ar) + +-- +2.39.5 (Apple Git-154) + diff --git a/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter-3.11.patch b/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter-3.11.patch new file mode 100644 index 00000000..4a9a7651 --- /dev/null +++ b/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter-3.11.patch @@ -0,0 +1,69 @@ +From a5182aec2c0597adb8a01298af120809fcf3187b Mon Sep 17 00:00:00 2001 +From: Geoffrey Thomas +Date: Sat, 19 Apr 2025 11:13:40 -0400 +Subject: [PATCH 1/1] configure: add --enable-static-libpython-for-interpreter + +This option changes the behavior of --enable-shared to continue to build +the libpython3.x.so shared library, but not use it for linking the +python3 interpreter executable. Instead, the executable is linked +directly against the libpython .o files as it would be with +--disable-shared. + +There are two benefits of this change. First, libpython uses +thread-local storage, which is noticeably slower when used in a loaded +module instead of in the main program, because the main program can take +advantage of constant offsets from the thread state pointer but loaded +modules have to dynamically call a function __tls_get_addr() to +potentially allocate their thread-local storage area. (There is another +thread-local storage model for dynamic libraries which mitigates most of +this performance hit, but it comes at the cost of preventing +dlopen("libpython3.x.so"), which is a use case we want to preserve.) + +Second, this improves the user experience around relocatable Python a +little bit, in that we don't need to use an $ORIGIN-relative path to +locate libpython3.x.so, which has some mild benefits around musl (which +does not support $ORIGIN-relative DT_NEEDED, only $ORIGIN-relative +DT_RPATH/DT_RUNPATH), users who want to make the interpreter setuid or +setcap (which prevents processing $ORIGIN), etc. +--- + configure.ac | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index ab5e1de6fab..6783c36da4d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1419,6 +1419,17 @@ fi], + [AC_MSG_RESULT(yes)]) + AC_SUBST(STATIC_LIBPYTHON) + ++AC_MSG_CHECKING([for --enable-static-libpython-for-interpreter]) ++AC_ARG_ENABLE([static-libpython-for-interpreter], ++ AS_HELP_STRING([--enable-static-libpython-for-interpreter], ++ [even with --enable-shared, statically link libpython into the interpreter (default is to use the shared library)])) ++ ++if test -z "$enable_static_libpython_for_interpreter" ++then ++ enable_static_libpython_for_interpreter="no" ++fi ++AC_MSG_RESULT([$enable_static_libpython_for_interpreter]) ++ + AC_MSG_CHECKING(for --enable-profiling) + AC_ARG_ENABLE(profiling, + AS_HELP_STRING([--enable-profiling], [enable C-level code profiling with gprof (default is no)])) +@@ -1563,7 +1574,11 @@ if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then + LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" + fi + # Link Python program to the shared library +- LINK_PYTHON_OBJS='$(BLDLIBRARY)' ++ if test "$enable_static_libpython_for_interpreter" = "yes"; then ++ LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' ++ else ++ LINK_PYTHON_OBJS='$(BLDLIBRARY)' ++ fi + else + if test "$STATIC_LIBPYTHON" = 0; then + # Build Python needs object files but don't need to build +-- +2.39.5 (Apple Git-154) + diff --git a/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter-3.9.patch b/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter-3.9.patch new file mode 100644 index 00000000..d2c0a45c --- /dev/null +++ b/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter-3.9.patch @@ -0,0 +1,93 @@ +From 5ae9112a87d45c3aff5ee269ff8e2e49ca278ed3 Mon Sep 17 00:00:00 2001 +From: Geoffrey Thomas +Date: Sat, 19 Apr 2025 11:13:40 -0400 +Subject: [PATCH 1/1] configure: add --enable-static-libpython-for-interpreter + +This option changes the behavior of --enable-shared to continue to build +the libpython3.x.so shared library, but not use it for linking the +python3 interpreter executable. Instead, the executable is linked +directly against the libpython .o files as it would be with +--disable-shared [in newer versions of Python]. + +There are two benefits of this change. First, libpython uses +thread-local storage, which is noticeably slower when used in a loaded +module instead of in the main program, because the main program can take +advantage of constant offsets from the thread state pointer but loaded +modules have to dynamically call a function __tls_get_addr() to +potentially allocate their thread-local storage area. (There is another +thread-local storage model for dynamic libraries which mitigates most of +this performance hit, but it comes at the cost of preventing +dlopen("libpython3.x.so"), which is a use case we want to preserve.) + +Second, this improves the user experience around relocatable Python a +little bit, in that we don't need to use an $ORIGIN-relative path to +locate libpython3.x.so, which has some mild benefits around musl (which +does not support $ORIGIN-relative DT_NEEDED, only $ORIGIN-relative +DT_RPATH/DT_RUNPATH), users who want to make the interpreter setuid or +setcap (which prevents processing $ORIGIN), etc. +--- + Makefile.pre.in | 4 +++- + configure.ac | 18 ++++++++++++++++++ + 2 files changed, 21 insertions(+), 1 deletion(-) + +diff --git a/Makefile.pre.in b/Makefile.pre.in +index a276d535c7f..193439aa73e 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -460,6 +460,8 @@ LIBRARY_OBJS= \ + $(LIBRARY_OBJS_OMIT_FROZEN) \ + Python/frozen.o + ++LINK_PYTHON_OBJS=@LINK_PYTHON_OBJS@ ++ + ########################################################################## + # DTrace + +@@ -589,7 +591,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c + + # Build the interpreter + $(BUILDPYTHON): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) $(EXPORTSYMS) +- $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) ++ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) + + platform: $(BUILDPYTHON) pybuilddir.txt + $(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform +diff --git a/configure.ac b/configure.ac +index aa515da4655..122b11def62 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1106,6 +1106,17 @@ then + fi + AC_MSG_RESULT($enable_shared) + ++AC_MSG_CHECKING([for --enable-static-libpython-for-interpreter]) ++AC_ARG_ENABLE([static-libpython-for-interpreter], ++ AS_HELP_STRING([--enable-static-libpython-for-interpreter], ++ [even with --enable-shared, statically link libpython into the interpreter (default is to use the shared library)])) ++ ++if test -z "$enable_static_libpython_for_interpreter" ++then ++ enable_static_libpython_for_interpreter="no" ++fi ++AC_MSG_RESULT([$enable_static_libpython_for_interpreter]) ++ + AC_MSG_CHECKING(for --enable-profiling) + AC_ARG_ENABLE(profiling, + AS_HELP_STRING([--enable-profiling], [enable C-level code profiling with gprof (default is no)])) +@@ -1211,6 +1222,13 @@ fi + + AC_MSG_RESULT($LDLIBRARY) + ++if test "$enable_static_libpython_for_interpreter" = "yes"; then ++ LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' ++else ++ LINK_PYTHON_OBJS='$(BLDLIBRARY)' ++fi ++AC_SUBST(LINK_PYTHON_OBJS) ++ + AC_SUBST(AR) + AC_CHECK_TOOLS(AR, ar aal, ar) + +-- +2.39.5 (Apple Git-154) + diff --git a/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter.patch b/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter.patch new file mode 100644 index 00000000..b8d23b52 --- /dev/null +++ b/cpython-unix/patch-python-configure-add-enable-static-libpython-for-interpreter.patch @@ -0,0 +1,86 @@ +From 439f6e6bb62482a98fb6765d723cedea12f3b10f Mon Sep 17 00:00:00 2001 +From: Geoffrey Thomas +Date: Sat, 19 Apr 2025 11:13:40 -0400 +Subject: [PATCH 1/1] configure: add --enable-static-libpython-for-interpreter + +This option changes the behavior of --enable-shared to continue to build +the libpython3.x.so shared library, but not use it for linking the +python3 interpreter executable. Instead, the executable is linked +directly against the libpython .o files as it would be with +--disable-shared. + +There are two benefits of this change. First, libpython uses +thread-local storage, which is noticeably slower when used in a loaded +module instead of in the main program, because the main program can take +advantage of constant offsets from the thread state pointer but loaded +modules have to dynamically call a function __tls_get_addr() to +potentially allocate their thread-local storage area. (There is another +thread-local storage model for dynamic libraries which mitigates most of +this performance hit, but it comes at the cost of preventing +dlopen("libpython3.x.so"), which is a use case we want to preserve.) + +Second, this improves the user experience around relocatable Python a +little bit, in that we don't need to use an $ORIGIN-relative path to +locate libpython3.x.so, which has some mild benefits around musl (which +does not support $ORIGIN-relative DT_NEEDED, only $ORIGIN-relative +DT_RPATH/DT_RUNPATH), users who want to make the interpreter setuid or +setcap (which prevents processing $ORIGIN), etc. +--- + configure.ac | 24 +++++++++++++++++++++--- + 1 file changed, 21 insertions(+), 3 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 004797b5233..a3a5ac1cdce 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1502,6 +1502,17 @@ fi], + [AC_MSG_RESULT([yes])]) + AC_SUBST([STATIC_LIBPYTHON]) + ++AC_MSG_CHECKING([for --enable-static-libpython-for-interpreter]) ++AC_ARG_ENABLE([static-libpython-for-interpreter], ++ AS_HELP_STRING([--enable-static-libpython-for-interpreter], ++ [even with --enable-shared, statically link libpython into the interpreter (default is to use the shared library)])) ++ ++if test -z "$enable_static_libpython_for_interpreter" ++then ++ enable_static_libpython_for_interpreter="no" ++fi ++AC_MSG_RESULT([$enable_static_libpython_for_interpreter]) ++ + AC_MSG_CHECKING([for --enable-profiling]) + AC_ARG_ENABLE([profiling], + AS_HELP_STRING([--enable-profiling], [enable C-level code profiling with gprof (default is no)])) +@@ -1660,7 +1671,11 @@ if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then + LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" + fi + # Link Python program to the shared library +- LINK_PYTHON_OBJS='$(BLDLIBRARY)' ++ if test "$enable_static_libpython_for_interpreter" = "yes"; then ++ LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' ++ else ++ LINK_PYTHON_OBJS='$(BLDLIBRARY)' ++ fi + else + if test "$STATIC_LIBPYTHON" = 0; then + # Build Python needs object files but don't need to build +@@ -2166,11 +2181,14 @@ if test "$Py_BOLT" = 'true' ; then + fi + fi + +-dnl Enable BOLT of libpython if built. ++dnl Enable BOLT of libpython if built and used by the python3 binary. ++dnl (If it is built but not used, we cannot profile it.) + AC_SUBST([BOLT_BINARIES]) + BOLT_BINARIES='$(BUILDPYTHON)' + AS_VAR_IF([enable_shared], [yes], [ +- BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)" ++ AS_VAR_IF([enable_static_libpython_for_interpreter], [no], [ ++ BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)" ++ ]) + ]) + + AC_ARG_VAR( +-- +2.39.5 (Apple Git-154) + diff --git a/cpython-unix/patch-python-configure-hacl-no-simd.patch b/cpython-unix/patch-python-configure-hacl-no-simd.patch new file mode 100644 index 00000000..125aea33 --- /dev/null +++ b/cpython-unix/patch-python-configure-hacl-no-simd.patch @@ -0,0 +1,24 @@ +diff --git a/configure.ac b/configure.ac +index a7b2f62579b..06c0c0c0da0 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -7897,8 +7897,7 @@ AC_SUBST([LIBHACL_LDFLAGS]) + # The SIMD files use aligned_alloc, which is not available on older versions of + # Android. + # The *mmintrin.h headers are x86-family-specific, so can't be used on WASI. +-if test "$ac_sys_system" != "Linux-android" -a "$ac_sys_system" != "WASI" || \ +- { test -n "$ANDROID_API_LEVEL" && test "$ANDROID_API_LEVEL" -ge 28; } ++if false + then + dnl This can be extended here to detect e.g. Power8, which HACL* should also support. + AX_CHECK_COMPILE_FLAG([-msse -msse2 -msse3 -msse4.1 -msse4.2],[ +@@ -7930,8 +7929,7 @@ AC_SUBST([LIBHACL_BLAKE2_SIMD128_OBJS]) + # Although AVX support is not guaranteed on Android + # (https://developer.android.com/ndk/guides/abis#86-64), this is safe because we do a + # runtime CPUID check. +-if test "$ac_sys_system" != "Linux-android" -a "$ac_sys_system" != "WASI" || \ +- { test -n "$ANDROID_API_LEVEL" && test "$ANDROID_API_LEVEL" -ge 28; } ++if false + then + AX_CHECK_COMPILE_FLAG([-mavx2],[ + [LIBHACL_SIMD256_FLAGS="-mavx2"] diff --git a/cpython-unix/patch-uuid-getnode-stable-3.13.patch b/cpython-unix/patch-uuid-getnode-stable-3.13.patch new file mode 100644 index 00000000..11bdf83a --- /dev/null +++ b/cpython-unix/patch-uuid-getnode-stable-3.13.patch @@ -0,0 +1,708 @@ +diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py +index e7e44c6413c2e2..ce396aa942b6ed 100755 +--- a/Lib/test/test_uuid.py ++++ b/Lib/test/test_uuid.py +@@ -1,6 +1,7 @@ + import unittest + from test import support + from test.support import import_helper ++from test.support.script_helper import assert_python_ok + import builtins + import contextlib + import copy +@@ -773,10 +774,37 @@ def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self): + class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase): + uuid = py_uuid + ++ + @unittest.skipUnless(c_uuid, 'requires the C _uuid module') + class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase): + uuid = c_uuid + ++ def check_has_stable_libuuid_extractable_node(self): ++ if not self.uuid._has_stable_extractable_node: ++ self.skipTest("libuuid cannot deduce MAC address") ++ ++ @unittest.skipUnless(os.name == 'posix', 'POSIX only') ++ def test_unix_getnode_from_libuuid(self): ++ self.check_has_stable_libuuid_extractable_node() ++ script = 'import uuid; print(uuid._unix_getnode())' ++ _, n_a, _ = assert_python_ok('-c', script) ++ _, n_b, _ = assert_python_ok('-c', script) ++ n_a, n_b = n_a.decode().strip(), n_b.decode().strip() ++ self.assertTrue(n_a.isdigit()) ++ self.assertTrue(n_b.isdigit()) ++ self.assertEqual(n_a, n_b) ++ ++ @unittest.skipUnless(os.name == 'nt', 'Windows only') ++ def test_windows_getnode_from_libuuid(self): ++ self.check_has_stable_libuuid_extractable_node() ++ script = 'import uuid; print(uuid._windll_getnode())' ++ _, n_a, _ = assert_python_ok('-c', script) ++ _, n_b, _ = assert_python_ok('-c', script) ++ n_a, n_b = n_a.decode().strip(), n_b.decode().strip() ++ self.assertTrue(n_a.isdigit()) ++ self.assertTrue(n_b.isdigit()) ++ self.assertEqual(n_a, n_b) ++ + + class BaseTestInternals: + _uuid = py_uuid +diff --git a/Lib/uuid.py b/Lib/uuid.py +index c286eac38e1ef4..6ab1658cc5249a 100644 +--- a/Lib/uuid.py ++++ b/Lib/uuid.py +@@ -572,22 +572,24 @@ def _netstat_getnode(): + try: + import _uuid + _generate_time_safe = getattr(_uuid, "generate_time_safe", None) ++ _has_stable_extractable_node = getattr(_uuid, "has_stable_extractable_node", False) + _UuidCreate = getattr(_uuid, "UuidCreate", None) + except ImportError: + _uuid = None + _generate_time_safe = None ++ _has_stable_extractable_node = False + _UuidCreate = None + + + def _unix_getnode(): + """Get the hardware address on Unix using the _uuid extension module.""" +- if _generate_time_safe: ++ if _generate_time_safe and _has_stable_extractable_node: + uuid_time, _ = _generate_time_safe() + return UUID(bytes=uuid_time).node + + def _windll_getnode(): + """Get the hardware address on Windows using the _uuid extension module.""" +- if _UuidCreate: ++ if _UuidCreate and _has_stable_extractable_node: + uuid_bytes = _UuidCreate() + return UUID(bytes_le=uuid_bytes).node + +diff --git a/Modules/_uuidmodule.c b/Modules/_uuidmodule.c +index c5e78b1510b5e3..c31a7e8fea5608 100644 +--- a/Modules/_uuidmodule.c ++++ b/Modules/_uuidmodule.c +@@ -78,23 +78,47 @@ py_UuidCreate(PyObject *Py_UNUSED(context), + return NULL; + } + ++static int ++py_windows_has_stable_node(void) ++{ ++ UUID uuid; ++ RPC_STATUS res; ++ Py_BEGIN_ALLOW_THREADS ++ res = UuidCreateSequential(&uuid); ++ Py_END_ALLOW_THREADS ++ return res == RPC_S_OK; ++} + #endif /* MS_WINDOWS */ + + + static int +-uuid_exec(PyObject *module) { ++uuid_exec(PyObject *module) ++{ ++#define ADD_INT(NAME, VALUE) \ ++ do { \ ++ if (PyModule_AddIntConstant(module, (NAME), (VALUE)) < 0) { \ ++ return -1; \ ++ } \ ++ } while (0) ++ + assert(sizeof(uuid_t) == 16); + #if defined(MS_WINDOWS) +- int has_uuid_generate_time_safe = 0; ++ ADD_INT("has_uuid_generate_time_safe", 0); + #elif defined(HAVE_UUID_GENERATE_TIME_SAFE) +- int has_uuid_generate_time_safe = 1; ++ ADD_INT("has_uuid_generate_time_safe", 1); + #else +- int has_uuid_generate_time_safe = 0; ++ ADD_INT("has_uuid_generate_time_safe", 0); + #endif +- if (PyModule_AddIntConstant(module, "has_uuid_generate_time_safe", +- has_uuid_generate_time_safe) < 0) { +- return -1; +- } ++ ++#if defined(MS_WINDOWS) ++ ADD_INT("has_stable_extractable_node", py_windows_has_stable_node()); ++#elif defined(HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC) ++ ADD_INT("has_stable_extractable_node", 1); ++#else ++ ADD_INT("has_stable_extractable_node", 0); ++#endif ++ ++#undef ADD_INT + return 0; + } + +diff --git a/configure b/configure +index 1cd1f690f7b9c1..cc976aafc09b34 100755 +--- a/configure ++++ b/configure +@@ -13381,6 +13381,7 @@ fi + + + ++ + have_uuid=missing + + for ac_header in uuid.h +@@ -13390,6 +13391,7 @@ if test "x$ac_cv_header_uuid_h" = xyes + then : + printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h + ++ + for ac_func in uuid_create uuid_enc_be + do : + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` +@@ -13399,7 +13401,9 @@ then : + cat >>confdefs.h <<_ACEOF + #define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 + _ACEOF +- have_uuid=yes ++ ++ have_uuid=yes ++ ac_cv_have_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + +@@ -13489,6 +13493,7 @@ if test "x$ac_cv_header_uuid_uuid_h" = xyes + then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h + ++ ac_cv_have_uuid_uuid_h=yes + py_check_lib_save_LIBS=$LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 + printf %s "checking for uuid_generate_time in -luuid... " >&6; } +@@ -13570,8 +13575,9 @@ fi + printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } + if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes + then : +- have_uuid=yes +- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h ++ ++ have_uuid=yes ++ ac_cv_have_uuid_generate_time_safe=yes + + fi + +@@ -13615,6 +13621,7 @@ if test "x$ac_cv_header_uuid_uuid_h" = xyes + then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h + ++ ac_cv_have_uuid_uuid_h=yes + py_check_lib_save_LIBS=$LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 + printf %s "checking for uuid_generate_time in -luuid... " >&6; } +@@ -13696,8 +13703,9 @@ fi + printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } + if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes + then : +- have_uuid=yes +- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h ++ ++ have_uuid=yes ++ ac_cv_have_uuid_generate_time_safe=yes + + fi + +@@ -13727,11 +13735,25 @@ else + LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + printf "%s\n" "yes" >&6; } ++<<<<<<< HEAD + have_uuid=yes + printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h + + printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h + ++======= ++ have_uuid=yes ++ ac_cv_have_uuid_generate_time_safe=yes ++ # The uuid.h file to include may be *or* . ++ # Since pkg-config --cflags uuid may return -I/usr/include/uuid, ++ # it's possible to write '#include ' in _uuidmodule.c, ++ # assuming that the compiler flags are properly updated. ++ # ++ # Ideally, we should have defined HAVE_UUID_H if and only if ++ # #include can be written, *without* assuming extra ++ # include path. ++ ac_cv_have_uuid_h=yes ++>>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) + + fi + +@@ -13752,6 +13774,7 @@ if test "x$ac_cv_func_uuid_generate_time" = xyes + then : + + have_uuid=yes ++ ac_cv_have_uuid_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + +@@ -13764,11 +13787,198 @@ done + + fi + ++<<<<<<< HEAD ++======= ++if test "x$ac_cv_have_uuid_h" = xyes ++then : ++ printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h ++ ++fi ++if test "x$ac_cv_have_uuid_uuid_h" = xyes ++then : ++ printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h ++ ++fi ++if test "x$ac_cv_have_uuid_generate_time_safe" = xyes ++then : ++ ++ printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h ++ ++ ++fi ++ ++# gh-124228: While the libuuid library is available on NetBSD, it supports only UUID version 4. ++# This restriction inhibits the proper generation of time-based UUIDs. ++if test "$ac_sys_system" = "NetBSD"; then ++ have_uuid=missing ++ printf "%s\n" "#define HAVE_UUID_H 0" >>confdefs.h ++ ++fi ++ ++>>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) + if test "x$have_uuid" = xmissing + then : + have_uuid=no + fi + ++# gh-132710: The UUID node is fetched by using libuuid when possible ++# and cached. While the node is constant within the same process, ++# different interpreters may have different values as libuuid may ++# randomize the node value if the latter cannot be deduced. ++# ++# Consumers may define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC ++# to indicate that libuuid is unstable and should not be relied ++# upon to deduce the MAC address. ++ ++ ++if test "$have_uuid" = "yes" -a "$HAVE_UUID_GENERATE_TIME_SAFE" = "1" ++then ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if uuid_generate_time_safe() node value is stable" >&5 ++printf %s "checking if uuid_generate_time_safe() node value is stable... " >&6; } ++ save_CFLAGS=$CFLAGS ++save_CPPFLAGS=$CPPFLAGS ++save_LDFLAGS=$LDFLAGS ++save_LIBS=$LIBS ++ ++ ++ # Be sure to add the extra include path if we used pkg-config ++ # as HAVE_UUID_H may be set even though is only reachable ++ # by adding extra -I flags. ++ # ++ # If the following script does not compile, we simply assume that ++ # libuuid is missing. ++ CFLAGS="$CFLAGS $LIBUUID_CFLAGS" ++ LIBS="$LIBS $LIBUUID_LIBS" ++ if test "$cross_compiling" = yes ++then : ++ ++ ++else case e in #( ++ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++ #include // PRIu64 ++ #include // uint64_t ++ #include // fopen(), fclose() ++ ++ #ifdef HAVE_UUID_H ++ #include ++ #else ++ #include ++ #endif ++ ++ #define ERR 1 ++ int main(void) { ++ uuid_t uuid; // unsigned char[16] ++ (void)uuid_generate_time_safe(uuid); ++ uint64_t node = 0; ++ for (size_t i = 0; i < 6; i++) { ++ node |= (uint64_t)uuid[15 - i] << (8 * i); ++ } ++ FILE *fp = fopen("conftest.out", "w"); ++ if (fp == NULL) { ++ return ERR; ++ } ++ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; ++ rc |= fclose(fp); ++ return rc == 0 ? 0 : ERR; ++ } ++_ACEOF ++if ac_fn_c_try_run "$LINENO" ++then : ++ ++ py_cv_uuid_node1=`cat conftest.out` ++ ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ;; ++esac ++fi ++ ++CFLAGS=$save_CFLAGS ++CPPFLAGS=$save_CPPFLAGS ++LDFLAGS=$save_LDFLAGS ++LIBS=$save_LIBS ++ ++ ++ save_CFLAGS=$CFLAGS ++save_CPPFLAGS=$CPPFLAGS ++save_LDFLAGS=$LDFLAGS ++save_LIBS=$LIBS ++ ++ ++ # Be sure to add the extra include path if we used pkg-config ++ # as HAVE_UUID_H may be set even though is only reachable ++ # by adding extra -I flags. ++ # ++ # If the following script does not compile, we simply assume that ++ # libuuid is missing. ++ CFLAGS="$CFLAGS $LIBUUID_CFLAGS" ++ LIBS="$LIBS $LIBUUID_LIBS" ++ if test "$cross_compiling" = yes ++then : ++ ++ ++else case e in #( ++ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++ #include // PRIu64 ++ #include // uint64_t ++ #include // fopen(), fclose() ++ ++ #ifdef HAVE_UUID_H ++ #include ++ #else ++ #include ++ #endif ++ ++ #define ERR 1 ++ int main(void) { ++ uuid_t uuid; // unsigned char[16] ++ (void)uuid_generate_time_safe(uuid); ++ uint64_t node = 0; ++ for (size_t i = 0; i < 6; i++) { ++ node |= (uint64_t)uuid[15 - i] << (8 * i); ++ } ++ FILE *fp = fopen("conftest.out", "w"); ++ if (fp == NULL) { ++ return ERR; ++ } ++ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; ++ rc |= fclose(fp); ++ return rc == 0 ? 0 : ERR; ++ } ++_ACEOF ++if ac_fn_c_try_run "$LINENO" ++then : ++ ++ py_cv_uuid_node2=`cat conftest.out` ++ ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ;; ++esac ++fi ++ ++CFLAGS=$save_CFLAGS ++CPPFLAGS=$save_CPPFLAGS ++LDFLAGS=$save_LDFLAGS ++LIBS=$save_LIBS ++ ++ ++ if test -n "$py_cv_uuid_node1" -a "$py_cv_uuid_node1" = "$py_cv_uuid_node2" ++ then ++ printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC 1" >>confdefs.h ++ ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: stable" >&5 ++printf "%s\n" "stable" >&6; } ++ else ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unstable" >&5 ++printf "%s\n" "unstable" >&6; } ++ fi ++fi ++ + # 'Real Time' functions on Solaris + # posix4 on Solaris 2.6 + # pthread (first!) on Linux +diff --git a/configure.ac b/configure.ac +index 3fcb18922c5330..9898af7ffd5f25 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3740,15 +3740,17 @@ dnl check for uuid dependencies + AH_TEMPLATE([HAVE_UUID_H], [Define to 1 if you have the header file.]) + AH_TEMPLATE([HAVE_UUID_UUID_H], [Define to 1 if you have the header file.]) + AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE], [Define if uuid_generate_time_safe() exists.]) ++AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC], [Define if uuid_generate_time_safe() is able to deduce a MAC address.]) + have_uuid=missing + + dnl AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 + dnl (anno 2007). FreeBSD and OpenBSD provides support in libc as well. + dnl Little-endian FreeBSD, OpenBSD and NetBSD needs encoding into an octet + dnl stream in big-endian byte-order +-AC_CHECK_HEADERS([uuid.h], +- [AC_CHECK_FUNCS([uuid_create uuid_enc_be], +- [have_uuid=yes ++AC_CHECK_HEADERS([uuid.h], [ ++ AC_CHECK_FUNCS([uuid_create uuid_enc_be], [ ++ have_uuid=yes ++ ac_cv_have_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + ]) +@@ -3758,19 +3760,29 @@ AS_VAR_IF([have_uuid], [missing], [ + PKG_CHECK_MODULES( + [LIBUUID], [uuid >= 2.20], + [dnl linux-util's libuuid has uuid_generate_time_safe() since v2.20 (2011) +- dnl and provides . ++ dnl and provides assuming specific include paths are given + have_uuid=yes +- AC_DEFINE([HAVE_UUID_H], [1]) +- AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) ++ ac_cv_have_uuid_generate_time_safe=yes ++ # The uuid.h file to include may be *or* . ++ # Since pkg-config --cflags uuid may return -I/usr/include/uuid, ++ # it's possible to write '#include ' in _uuidmodule.c, ++ # assuming that the compiler flags are properly updated. ++ # ++ # Ideally, we should have defined HAVE_UUID_H if and only if ++ # #include can be written, *without* assuming extra ++ # include path. ++ ac_cv_have_uuid_h=yes + ], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" + LIBS="$LIBS $LIBUUID_LIBS" + AC_CHECK_HEADERS([uuid/uuid.h], [ ++ ac_cv_have_uuid_uuid_h=yes + PY_CHECK_LIB([uuid], [uuid_generate_time], [have_uuid=yes]) +- PY_CHECK_LIB([uuid], [uuid_generate_time_safe], +- [have_uuid=yes +- AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) ]) ]) ++ PY_CHECK_LIB([uuid], [uuid_generate_time_safe], [ ++ have_uuid=yes ++ ac_cv_have_uuid_generate_time_safe=yes ++ ])]) + AS_VAR_IF([have_uuid], [yes], [ + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} +@@ -3785,14 +3797,90 @@ AS_VAR_IF([have_uuid], [missing], [ + AC_CHECK_HEADERS([uuid/uuid.h], [ + AC_CHECK_FUNC([uuid_generate_time], [ + have_uuid=yes ++ ac_cv_have_uuid_uuid_h=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + ]) + ]) + ]) + ++AS_VAR_IF([ac_cv_have_uuid_h], [yes], [AC_DEFINE([HAVE_UUID_H], [1])]) ++AS_VAR_IF([ac_cv_have_uuid_uuid_h], [yes], [AC_DEFINE([HAVE_UUID_UUID_H], [1])]) ++AS_VAR_IF([ac_cv_have_uuid_generate_time_safe], [yes], [ ++ AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) ++]) ++ ++# gh-124228: While the libuuid library is available on NetBSD, it supports only UUID version 4. ++# This restriction inhibits the proper generation of time-based UUIDs. ++if test "$ac_sys_system" = "NetBSD"; then ++ have_uuid=missing ++ AC_DEFINE([HAVE_UUID_H], [0]) ++fi ++ + AS_VAR_IF([have_uuid], [missing], [have_uuid=no]) + ++# gh-132710: The UUID node is fetched by using libuuid when possible ++# and cached. While the node is constant within the same process, ++# different interpreters may have different values as libuuid may ++# randomize the node value if the latter cannot be deduced. ++# ++# Consumers may define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC ++# to indicate that libuuid is unstable and should not be relied ++# upon to deduce the MAC address. ++AC_DEFUN([PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC], [WITH_SAVE_ENV([ ++ # Be sure to add the extra include path if we used pkg-config ++ # as HAVE_UUID_H may be set even though is only reachable ++ # by adding extra -I flags. ++ # ++ # If the following script does not compile, we simply assume that ++ # libuuid is missing. ++ CFLAGS="$CFLAGS $LIBUUID_CFLAGS" ++ LIBS="$LIBS $LIBUUID_LIBS" ++ AC_RUN_IFELSE([AC_LANG_SOURCE([[ ++ #include // PRIu64 ++ #include // uint64_t ++ #include // fopen(), fclose() ++ ++ #ifdef HAVE_UUID_H ++ #include ++ #else ++ #include ++ #endif ++ ++ #define ERR 1 ++ int main(void) { ++ uuid_t uuid; // unsigned char[16] ++ (void)uuid_generate_time_safe(uuid); ++ uint64_t node = 0; ++ for (size_t i = 0; i < 6; i++) { ++ node |= (uint64_t)uuid[15 - i] << (8 * i); ++ } ++ FILE *fp = fopen("conftest.out", "w"); ++ if (fp == NULL) { ++ return ERR; ++ } ++ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0; ++ rc |= fclose(fp); ++ return rc == 0 ? 0 : ERR; ++ }]])], [ ++ AS_VAR_SET([$1], [`cat conftest.out`]) ++ ], [], [] ++ )])]) ++ ++if test "$have_uuid" = "yes" -a "$HAVE_UUID_GENERATE_TIME_SAFE" = "1" ++then ++ AC_MSG_CHECKING([if uuid_generate_time_safe() node value is stable]) ++ PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC([py_cv_uuid_node1]) ++ PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC([py_cv_uuid_node2]) ++ if test -n "$py_cv_uuid_node1" -a "$py_cv_uuid_node1" = "$py_cv_uuid_node2" ++ then ++ AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC], [1]) ++ AC_MSG_RESULT([stable]) ++ else ++ AC_MSG_RESULT([unstable]) ++ fi ++fi ++ + # 'Real Time' functions on Solaris + # posix4 on Solaris 2.6 + # pthread (first!) on Linux +diff --git a/pyconfig.h.in b/pyconfig.h.in +index 3c16c694c84599..73358a0f35ae82 100644 +--- a/pyconfig.h.in ++++ b/pyconfig.h.in +@@ -1548,6 +1548,9 @@ + /* Define if uuid_generate_time_safe() exists. */ + #undef HAVE_UUID_GENERATE_TIME_SAFE + ++/* Define if uuid_generate_time_safe() is able to deduce a MAC address. */ ++#undef HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_UUID_H + + +From cb0f32a7d64b6dc4a63c4a683bb52a97ebe1d78a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= + <10796600+picnixz@users.noreply.github.com> +Date: Mon, 26 May 2025 12:34:00 +0200 +Subject: [PATCH 2/2] rgen + +--- + configure | 25 ++++++------------------- + 1 file changed, 6 insertions(+), 19 deletions(-) + +diff --git a/configure b/configure +index cc976aafc09b34..47e4f29e23a7ac 100755 +--- a/configure ++++ b/configure +@@ -13735,14 +13735,7 @@ else + LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + printf "%s\n" "yes" >&6; } +-<<<<<<< HEAD + have_uuid=yes +- printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h +- +- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h +- +-======= +- have_uuid=yes + ac_cv_have_uuid_generate_time_safe=yes + # The uuid.h file to include may be *or* . + # Since pkg-config --cflags uuid may return -I/usr/include/uuid, +@@ -13753,7 +13746,6 @@ printf "%s\n" "yes" >&6; } + # #include can be written, *without* assuming extra + # include path. + ac_cv_have_uuid_h=yes +->>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) + + fi + +@@ -13787,8 +13779,6 @@ done + + fi + +-<<<<<<< HEAD +-======= + if test "x$ac_cv_have_uuid_h" = xyes + then : + printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h +@@ -13815,7 +13805,6 @@ if test "$ac_sys_system" = "NetBSD"; then + + fi + +->>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901)) + if test "x$have_uuid" = xmissing + then : + have_uuid=no +@@ -13853,8 +13842,8 @@ save_LIBS=$LIBS + then : + + +-else case e in #( +- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++else $as_nop ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + #include // PRIu64 +@@ -13891,8 +13880,7 @@ then : + + fi + rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +-esac ++ conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + + CFLAGS=$save_CFLAGS +@@ -13919,8 +13907,8 @@ save_LIBS=$LIBS + then : + + +-else case e in #( +- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++else $as_nop ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + + #include // PRIu64 +@@ -13957,8 +13945,7 @@ then : + + fi + rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +-esac ++ conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + + CFLAGS=$save_CFLAGS diff --git a/cpython-unix/sccache-wrapper.sh b/cpython-unix/sccache-wrapper.sh deleted file mode 100755 index 6eb63fb2..00000000 --- a/cpython-unix/sccache-wrapper.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash -# This script is needed to handle a race in GCC's build system and a bug in -# sccache. -# -# GCC's build system could materialize `xgcc` and invoke commands like -# `xgcc -dumpspecs` before make materializes `cc1`. This is relevant because -# sccache invokes ` -E` on the first invocation of a compiler to -# determine which flavor of compiler to treat it as. And `gcc -E` requires -# support binaries like `cc1` in order to work. Our wrapper script sniffs -# for existence of `cc1` to mitigate this race condiion. -# -# Furthermore, sccache doesn't honor `-B` arguments when running -# ` -E`. So even if a support binary like `cc1` may exist, GCC may -# not know where to find it. Our wrapper script works around this by ensuring -# the compiler's directory is always on PATH. -# -# This script/approach is arguably not sound for use outside of the value of -# STAGE_CC_WRAPPER in GCC's build system. You have been warned. - -set -o errexit -set -o pipefail - -dir=$(dirname $1) -cc1=${dir}/cc1 - -if [ -e "${cc1}" ]; then - export PATH=${dir}:${PATH} - exec sccache "$@" -else - exec "$@" -fi diff --git a/cpython-unix/targets.yml b/cpython-unix/targets.yml index 1b179768..95ef58b2 100644 --- a/cpython-unix/targets.yml +++ b/cpython-unix/targets.yml @@ -61,7 +61,8 @@ # 11.0+. aarch64-apple-darwin: host_platforms: - - macos + - macos_arm64 + - macos_x86_64 pythons_supported: - '3.9' - '3.10' @@ -111,7 +112,8 @@ aarch64-apple-darwin: aarch64-apple-ios: host_platforms: - - macos + - macos_arm64 + - macos_x86_64 pythons_supported: - '3.9' needs_toolchain: true @@ -153,7 +155,8 @@ aarch64-apple-ios: aarch64-unknown-linux-gnu: host_platforms: - - linux64 + - linux_x86_64 + - linux_aarch64 pythons_supported: - '3.9' - '3.10' @@ -161,11 +164,16 @@ aarch64-unknown-linux-gnu: - '3.12' - '3.13' - '3.14' - docker_image_suffix: .cross - host_cc: /usr/bin/x86_64-linux-gnu-gcc - host_cxx: /usr/bin/x86_64-linux-gnu-g++ - target_cc: /usr/bin/aarch64-linux-gnu-gcc - target_cxx: /usr/bin/aarch64-linux-gnu-g++ + docker_image_suffix: .debian9 + needs_toolchain: true + host_cc: clang + host_cxx: clang++ + target_cc: clang + target_cxx: clang++ + target_cflags: + - '-fvisibility=hidden' + # Needed to prevent BOLT from crashing. + - '-fdebug-default-version=4' needs: - autoconf - bdb @@ -191,10 +199,16 @@ aarch64-unknown-linux-gnu: - xz - zlib openssl_target: linux-aarch64 + # Blocked on: + # BOLT-ERROR: Cannot relax adr in non-simple function + # trampoline_code_table/1. Use --strict option to override + # See https://github.com/llvm/llvm-project/issues/146541 + # bolt_capable: true arm64-apple-tvos: host_platforms: - - macos + - macos_arm64 + - macos_x86_64 pythons_supported: - '3.9' needs_toolchain: true @@ -235,7 +249,7 @@ arm64-apple-tvos: armv7-unknown-linux-gnueabi: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -276,7 +290,7 @@ armv7-unknown-linux-gnueabi: armv7-unknown-linux-gnueabihf: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -315,55 +329,9 @@ armv7-unknown-linux-gnueabihf: - zlib openssl_target: linux-armv4 -i686-unknown-linux-gnu: - host_platforms: - - linux64 - pythons_supported: - - '3.9' - - '3.10' - - '3.11' - - '3.12' - - '3.13' - - '3.14' - needs_toolchain: true - host_cc: clang - host_cxx: clang++ - target_cc: clang - target_cxx: clang++ - target_cflags: - - '-m32' - - '-fvisibility=hidden' - target_ldflags: - - '-m32' - needs: - - autoconf - - bdb - - binutils - - bzip2 - - expat - - libedit - - libffi - - libX11 - - libXau - - libxcb - - m4 - - mpdecimal - - ncurses - - openssl-3.0 - - patchelf - - sqlite - - tcl - - tk - - tix - - uuid - - xorgproto - - xz - - zlib - openssl_target: linux-x86-clang - mips-unknown-linux-gnu: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -404,7 +372,7 @@ mips-unknown-linux-gnu: mipsel-unknown-linux-gnu: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -445,7 +413,7 @@ mipsel-unknown-linux-gnu: ppc64le-unknown-linux-gnu: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -486,7 +454,7 @@ ppc64le-unknown-linux-gnu: riscv64-unknown-linux-gnu: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -527,7 +495,7 @@ riscv64-unknown-linux-gnu: s390x-unknown-linux-gnu: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -568,7 +536,8 @@ s390x-unknown-linux-gnu: thumb7k-apple-watchos: host_platforms: - - macos + - macos_arm64 + - macos_x86_64 pythons_supported: - '3.9' needs_toolchain: true @@ -613,7 +582,8 @@ thumb7k-apple-watchos: # machines. x86_64-apple-darwin: host_platforms: - - macos + - macos_arm64 + - macos_x86_64 pythons_supported: - '3.9' - '3.10' @@ -663,7 +633,8 @@ x86_64-apple-darwin: x86_64-apple-ios: host_platforms: - - macos + - macos_arm64 + - macos_x86_64 pythons_supported: - '3.9' needs_toolchain: true @@ -705,7 +676,8 @@ x86_64-apple-ios: x86_64-apple-tvos: host_platforms: - - macos + - macos_arm64 + - macos_x86_64 pythons_supported: - '3.9' needs_toolchain: true @@ -746,7 +718,8 @@ x86_64-apple-tvos: x86_64-apple-watchos: host_platforms: - - macos + - macos_arm64 + - macos_x86_64 pythons_supported: - '3.9' needs_toolchain: true @@ -787,7 +760,7 @@ x86_64-apple-watchos: x86_64-unknown-linux-gnu: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -833,7 +806,7 @@ x86_64-unknown-linux-gnu: x86_64_v2-unknown-linux-gnu: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -880,7 +853,7 @@ x86_64_v2-unknown-linux-gnu: x86_64_v3-unknown-linux-gnu: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -927,7 +900,7 @@ x86_64_v3-unknown-linux-gnu: x86_64_v4-unknown-linux-gnu: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -974,7 +947,7 @@ x86_64_v4-unknown-linux-gnu: x86_64-unknown-linux-musl: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -1018,7 +991,7 @@ x86_64-unknown-linux-musl: x86_64_v2-unknown-linux-musl: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -1063,7 +1036,7 @@ x86_64_v2-unknown-linux-musl: x86_64_v3-unknown-linux-musl: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' @@ -1108,7 +1081,7 @@ x86_64_v3-unknown-linux-musl: x86_64_v4-unknown-linux-musl: host_platforms: - - linux64 + - linux_x86_64 pythons_supported: - '3.9' - '3.10' diff --git a/cpython-unix/xcb.Dockerfile b/cpython-unix/xcb.Dockerfile deleted file mode 100644 index 33d350e2..00000000 --- a/cpython-unix/xcb.Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -{% include 'build.Dockerfile' %} -RUN ulimit -n 10000 && apt-get install \ - python diff --git a/cpython-unix/xcb.cross-riscv64.Dockerfile b/cpython-unix/xcb.cross-riscv64.Dockerfile deleted file mode 100644 index 260aa7d7..00000000 --- a/cpython-unix/xcb.cross-riscv64.Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -{% include 'build.cross-riscv64.Dockerfile' %} -RUN apt-get install \ - python diff --git a/cpython-unix/xcb.cross.Dockerfile b/cpython-unix/xcb.cross.Dockerfile deleted file mode 100644 index cc003ff2..00000000 --- a/cpython-unix/xcb.cross.Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -{% include 'build.cross.Dockerfile' %} -RUN apt-get install \ - python diff --git a/cpython-windows/build.py b/cpython-windows/build.py index 7e4d78ac..3b0c3b41 100644 --- a/cpython-windows/build.py +++ b/cpython-windows/build.py @@ -72,6 +72,10 @@ }, "_overlapped": {}, "_multiprocessing": {}, + "_remote_debugging": { + # Added in 3.14 + "ignore_missing": True + }, "_socket": {}, "_sqlite3": {"shared_depends": ["sqlite3"]}, # See the one-off calls to copy_link_to_lib() and elsewhere to hack up @@ -90,6 +94,10 @@ "ignore_missing": True, }, "_zoneinfo": {"ignore_missing": True}, + "_zstd": { + # Added in 3.14 + "ignore_missing": True + }, "pyexpat": {}, "select": {}, "unicodedata": {}, @@ -117,6 +125,7 @@ "_tkinter": ["tcl-8612", "tk-8612", "tix"], "_uuid": ["uuid"], "zlib": ["zlib"], + "_zstd": ["zstd"], } @@ -346,6 +355,7 @@ def hack_props( pcbuild_path: pathlib.Path, arch: str, python_version: str, + zlib_entry: str, ): # TODO can we pass props into msbuild.exe? @@ -355,11 +365,12 @@ def hack_props( bzip2_version = DOWNLOADS["bzip2"]["version"] sqlite_version = DOWNLOADS["sqlite"]["version"] xz_version = DOWNLOADS["xz"]["version"] - zlib_version = DOWNLOADS["zlib"]["version"] + zlib_version = DOWNLOADS[zlib_entry]["version"] + zstd_version = DOWNLOADS["zstd"]["version"] mpdecimal_version = DOWNLOADS["mpdecimal"]["version"] - if meets_python_minimum_version(python_version, "3.14"): + if meets_python_minimum_version(python_version, "3.14") or arch == "arm64": tcltk_commit = DOWNLOADS["tk-windows-bin"]["git_commit"] else: tcltk_commit = DOWNLOADS["tk-windows-bin-8612"]["git_commit"] @@ -369,7 +380,9 @@ def hack_props( libffi_path = td / "libffi" tcltk_path = td / ("cpython-bin-deps-%s" % tcltk_commit) xz_path = td / ("xz-%s" % xz_version) - zlib_path = td / ("zlib-%s" % zlib_version) + zlib_prefix = "cpython-source-deps-" if zlib_entry == "zlib-ng" else "" + zlib_path = td / ("%s%s-%s" % (zlib_prefix, zlib_entry, zlib_version)) + zstd_path = td / ("cpython-source-deps-zstd-%s" % zstd_version) mpdecimal_path = td / ("mpdecimal-%s" % mpdecimal_version) openssl_root = td / "openssl" / arch @@ -410,6 +423,13 @@ def hack_props( elif b"%s\\" % zlib_path + # On 3.14+, it's zlib-ng and the name changed + elif b"%s\\" % zlib_path + + elif b"%s\\" % zstd_path + elif b"%s\\" % mpdecimal_path @@ -444,6 +464,8 @@ def hack_props( suffix = b"-x64" elif arch == "win32": suffix = b"" + elif arch == "arm64": + suffix = b"" else: raise Exception("unhandled architecture: %s" % arch) @@ -484,6 +506,8 @@ def hack_project_files( cpython_source_path: pathlib.Path, build_directory: str, python_version: str, + zlib_entry: str, + arch: str, ): """Hacks Visual Studio project files to work with our build.""" @@ -494,8 +518,20 @@ def hack_project_files( pcbuild_path, build_directory, python_version, + zlib_entry, ) + # `--include-tcltk` is forced off on arm64, undo that + # See https://github.com/python/cpython/pull/132650 + try: + static_replace_in_file( + cpython_source_path / "PC" / "layout" / "main.py", + rb'if ns.arch in ("arm32", "arm64"):', + rb'if ns.arch == "arm32":', + ) + except NoSearchStringError: + pass + # Our SQLite directory is named weirdly. This throws off version detection # in the project file. Replace the parsing logic with a static string. sqlite3_version = DOWNLOADS["sqlite"]["actual_version"].encode("ascii") @@ -581,14 +617,18 @@ def hack_project_files( # have a standalone zlib DLL, so we remove references to it. For Python # 3.14+, we're using tk-windows-bin 8.6.14 which includes a prebuilt zlib # DLL, so we skip this patch there. - if meets_python_minimum_version( - python_version, "3.12" - ) and meets_python_maximum_version(python_version, "3.13"): - static_replace_in_file( - pcbuild_path / "_tkinter.vcxproj", - rb'<_TclTkDLL Include="$(tcltkdir)\bin\$(tclZlibDllName)" />', - rb"", - ) + # On arm64, we use the new version of tk-windows-bin for all versions. + if meets_python_minimum_version(python_version, "3.12") and ( + meets_python_maximum_version(python_version, "3.13") or arch == "arm64" + ): + try: + static_replace_in_file( + pcbuild_path / "_tkinter.vcxproj", + rb'<_TclTkDLL Include="$(tcltkdir)\bin\$(tclZlibDllName)" />', + rb"", + ) + except NoSearchStringError: + pass # We don't need to produce python_uwp.exe and its *w variant. Or the # python3.dll, pyshellext, or pylauncher. @@ -708,9 +748,11 @@ def build_openssl_for_arch( elif arch == "amd64": configure = "VC-WIN64A" prefix = "64" + elif arch == "arm64": + configure = "VC-WIN64-ARM" + prefix = "arm64" else: - print("invalid architecture: %s" % arch) - sys.exit(1) + raise Exception("unhandled architecture: %s" % arch) # The official CPython OpenSSL builds hack ms/uplink.c to change the # ``GetModuleHandle(NULL)`` invocation to load things from _ssl.pyd @@ -758,6 +800,12 @@ def build_openssl_for_arch( log("copying %s to %s" % (source, dest)) shutil.copyfile(source, dest) + # Copy `applink.c` to the include directory. + source_applink = source_root / "ms" / "applink.c" + dest_applink = install_root / "include" / "openssl" / "applink.c" + log("copying %s to %s" % (source_applink, dest_applink)) + shutil.copyfile(source_applink, dest_applink) + def build_openssl( entry: str, @@ -779,6 +827,7 @@ def build_openssl( root_32 = td / "x86" root_64 = td / "x64" + root_arm64 = td / "arm64" if arch == "x86": root_32.mkdir() @@ -802,13 +851,28 @@ def build_openssl( root_64, jom_archive=jom_archive, ) + elif arch == "arm64": + root_arm64.mkdir() + build_openssl_for_arch( + perl_path, + "arm64", + openssl_archive, + openssl_version, + nasm_archive, + root_arm64, + jom_archive=jom_archive, + ) else: - raise ValueError("unhandled arch: %s" % arch) + raise Exception("unhandled architecture: %s" % arch) install = td / "out" if arch == "x86": shutil.copytree(root_32 / "install" / "32", install / "openssl" / "win32") + elif arch == "arm64": + shutil.copytree( + root_arm64 / "install" / "arm64", install / "openssl" / "arm64" + ) else: shutil.copytree(root_64 / "install" / "64", install / "openssl" / "amd64") @@ -879,9 +943,14 @@ def build_libffi( if arch == "x86": args.append("-x86") artifacts_path = ffi_source_path / "i686-pc-cygwin" - else: + elif arch == "arm64": + args.append("-arm64") + artifacts_path = ffi_source_path / "aarch64-w64-cygwin" + elif arch == "amd64": args.append("-x64") artifacts_path = ffi_source_path / "x86_64-w64-cygwin" + else: + raise Exception("unhandled architecture: %s" % arch) subprocess.run(args, env=env, check=True) @@ -913,6 +982,7 @@ def collect_python_build_artifacts( arch: str, config: str, openssl_entry: str, + zlib_entry: str, freethreaded: bool, ): """Collect build artifacts from Python. @@ -995,6 +1065,9 @@ def collect_python_build_artifacts( "sqlite3", } + if zlib_entry == "zlib-ng": + depends_projects |= {"zlib-ng"} + known_projects = ( ignore_projects | other_projects | depends_projects | extension_projects ) @@ -1043,8 +1116,10 @@ def find_additional_dependencies(project: pathlib.Path): abi_platform = "win_amd64" elif arch == "win32": abi_platform = "win32" + elif arch == "arm64": + abi_platform = "win_arm64" else: - raise ValueError("unhandled arch: %s" % arch) + raise Exception("unhandled architecture: %s" % arch) if freethreaded: abi_tag = ".cp%st-%s" % (python_majmin, abi_platform) @@ -1142,8 +1217,11 @@ def find_additional_dependencies(project: pathlib.Path): if name == "openssl": name = openssl_entry - # On 3.14+, we use the latest tcl/tk version - if ext == "_tkinter" and python_majmin == "314": + if name == "zlib": + name = zlib_entry + + # On 3.14+ and aarch64, we use the latest tcl/tk version + if ext == "_tkinter" and (python_majmin == "314" or arch == "arm64"): name = name.replace("-8612", "") download_entry = DOWNLOADS[name] @@ -1213,29 +1291,40 @@ def build_cpython( # The python.props file keys off MSBUILD, so it needs to be set. os.environ["MSBUILD"] = str(msbuild) - bzip2_archive = download_entry("bzip2", BUILD) - sqlite_archive = download_entry("sqlite", BUILD) - xz_archive = download_entry("xz", BUILD) - zlib_archive = download_entry("zlib", BUILD) - python_archive = download_entry(python_entry_name, BUILD) entry = DOWNLOADS[python_entry_name] - python_version = entry["version"] + zlib_entry = ( + "zlib-ng" if meets_python_minimum_version(python_version, "3.14") else "zlib" + ) + + bzip2_archive = download_entry("bzip2", BUILD) + sqlite_archive = download_entry("sqlite", BUILD) + xz_archive = download_entry("xz", BUILD) + zlib_archive = download_entry(zlib_entry, BUILD) + setuptools_wheel = download_entry("setuptools", BUILD) pip_wheel = download_entry("pip", BUILD) - # On CPython 3.14+, we use the latest tcl/tk version which has additional runtime - # dependencies, so we are conservative and use the old version elsewhere. + # On CPython 3.14+, we use the latest tcl/tk version which has additional + # runtime dependencies, so we are conservative and use the old version + # elsewhere. The old version isn't built for arm64, so we use the new + # version there too + tk_bin_entry = ( + "tk-windows-bin" + if meets_python_minimum_version(python_version, "3.14") or arch == "arm64" + else "tk-windows-bin-8612" + ) + tk_bin_archive = download_entry( + tk_bin_entry, BUILD, local_name="tk-windows-bin.tar.gz" + ) + + # On CPython 3.14+, zstd is included if meets_python_minimum_version(python_version, "3.14"): - tk_bin_archive = download_entry( - "tk-windows-bin", BUILD, local_name="tk-windows-bin.tar.gz" - ) + zstd_archive = download_entry("zstd", BUILD) else: - tk_bin_archive = download_entry( - "tk-windows-bin-8612", BUILD, local_name="tk-windows-bin.tar.gz" - ) + zstd_archive = None # CPython 3.13+ no longer uses a bundled `mpdecimal` version so we build it if meets_python_minimum_version(python_version, "3.13"): @@ -1259,8 +1348,11 @@ def build_cpython( elif arch == "x86": build_platform = "win32" build_directory = "win32" + elif arch == "arm64": + build_platform = "arm64" + build_directory = "arm64" else: - raise ValueError("unhandled arch: %s" % arch) + raise Exception("unhandled architecture: %s" % arch) tempdir_opts = ( {"ignore_cleanup_errors": True} if sys.version_info >= (3, 12) else {} @@ -1279,6 +1371,7 @@ def build_cpython( tk_bin_archive, xz_archive, zlib_archive, + zstd_archive, ): if a is None: continue @@ -1293,7 +1386,7 @@ def build_cpython( # We need all the OpenSSL library files in the same directory to appease # install rules. - openssl_arch = {"amd64": "amd64", "x86": "win32"}[arch] + openssl_arch = {"amd64": "amd64", "x86": "win32", "arm64": "arm64"}[arch] openssl_root = td / "openssl" / openssl_arch openssl_bin_path = openssl_root / "bin" openssl_lib_path = openssl_root / "lib" @@ -1307,6 +1400,18 @@ def build_cpython( log("copying %s to %s" % (source, dest)) shutil.copyfile(source, dest) + # Delete the tk nmake helper, it's not needed and links msvc + if tk_bin_entry == "tk-windows-bin": + tcltk_commit: str = DOWNLOADS[tk_bin_entry]["git_commit"] + tcltk_path = td / ("cpython-bin-deps-%s" % tcltk_commit) + ( + tcltk_path + / build_directory + / "lib" + / "nmake" + / "x86_64-w64-mingw32-nmakehlp.exe" + ).unlink() + cpython_source_path = td / ("Python-%s" % python_version) pcbuild_path = cpython_source_path / "PCbuild" @@ -1328,6 +1433,8 @@ def build_cpython( cpython_source_path, build_directory, python_version=python_version, + zlib_entry=zlib_entry, + arch=arch, ) if pgo: @@ -1528,6 +1635,7 @@ def build_cpython( build_directory, artifact_config, openssl_entry=openssl_entry, + zlib_entry=zlib_entry, freethreaded=freethreaded, ) @@ -1749,9 +1857,14 @@ def main() -> None: if os.environ.get("Platform") == "x86": target_triple = "i686-pc-windows-msvc" arch = "x86" - else: + elif os.environ.get("Platform") == "arm64": + target_triple = "aarch64-pc-windows-msvc" + arch = "arm64" + elif os.environ.get("Platform") == "x64": target_triple = "x86_64-pc-windows-msvc" arch = "amd64" + else: + raise Exception("unhandled architecture: %s" % os.environ.get("Platform")) # TODO need better dependency checking. diff --git a/docs/building.rst b/docs/building.rst index dc91dea2..c6a07e25 100644 --- a/docs/building.rst +++ b/docs/building.rst @@ -104,38 +104,3 @@ You will need to specify the path to a ``sh.exe`` installed from cygwin. e.g. To build a 32-bit x86 binary, simply use an ``x86 Native Tools Command Prompt`` instead of ``x64``. - -Using sccache to Speed up Builds -================================ - -Builds can take a long time. - -python-build-standalone can automatically detect and use the -`sccache `_ compiler cache to speed -up subsequent builds on UNIX-like platforms. ``sccache`` can shave dozens -of minutes from fresh builds, even on a 16 core CPU! - -If there is an executable ``sccache`` in the source directory, it will -automatically be copied into the build environment and used. For non-container -builds, an ``sccache`` executable is also searched for on ``PATH``. - -The ``~/.python-build-standalone-env`` file is read if it exists (the format is -``key=value`` pairs) and variables are added to the build environment. - -In addition, environment variables ``AWS_ACCESS_KEY_ID``, -``AWS_SECRET_ACCESS_KEY``, and any variable beginning with ``SCCACHE_`` are -automatically added to the build environment. - -The environment variable support enables you to define remote build caches -(such as S3 buckets) to provide a persistent, shared cache across builds and -machines. - -Keep in mind that when performing builds in containers in Linux (the default -behavior), the local filesystem is local to the container and does not survive -the build of a single package. So sccache is practically meaningless unless -configured to use an external store (such as S3). - -When using remote stores (such as S3), ``sccache`` can be constrained on -network I/O. We recommend having at least a 100mbps network connection to -a remote store and employing a network store with as little latency as possible -for best results. diff --git a/docs/quirks.rst b/docs/quirks.rst index 77e4d4fe..8900cd6a 100644 --- a/docs/quirks.rst +++ b/docs/quirks.rst @@ -4,17 +4,21 @@ Behavior Quirks =============== +While these Python distributions are intended to be broadly compatible +with the Python ecosystem, there are a few known behavior quirks that +affect specific environments, packages, or use cases. + .. _quirk_backspace_key: -Backspace Key Doesn't work in Python REPL -========================================= +If special keys do not work in the Python REPL +============================================== If you attempt to run ``python`` and the backspace key doesn't erase characters or the arrow keys don't work as expected, this is because the executable can't find the *terminfo database*. -A telltale sign of this is the Python REPL printing the following -on startup:: +If this happens, the Python REPL will print the following warning +message on startup:: Cannot read termcap database; using dumb terminal settings. @@ -35,42 +39,27 @@ you build a program (like Python) locally, you link against ``readline`` or ``libedit`` and get these default locations *for free*. -Because python-build-standalone Python distributions compile -and use their own version of ``libedit`` and because the build -environment is different from your machine, the default search -locations for the *terminfo database* built into binaries -distributed with this project may point to a path that doesn't -exist. The *terminfo database* cannot be located and ``libedit`` -does not know how to convert special key presses to special behavior. - -The solution to this is to set an environment variable -with the location of the *terminfo database*. - -If running a Debian based Linux distribution (including Ubuntu):: - - $ TERMINFO_DIRS=/etc/terminfo:/lib/terminfo:/usr/share/terminfo - -If running a RedHat based Linux distribution:: - - $ TERMINFO_DIRS=/etc/terminfo:/usr/share/terminfo +These Python distributions compile and use their own version of +``libedit`` to avoid a dependency on what is (or isn't) installed on +your system. This means that they do not use your system-provided +libraries for reading the *terminfo database*. This version of +``libedit`` is configured to look for in locations that should work for +most OSes (specifically, ``/usr/share/terminfo`` on macOS, and +``/etc/terminfo``, ``/lib/terminfo``, and ``/usr/share/terminfo`` on +Linux, which should cover all major Linux distributions), but it is +possible that your environment has it somewhere else. If your OS stores +the *terminfo database* in an uncommon location, you can set the +``TERMINFO_DIRS`` environment variable so that ``libedit`` can find it. -If running macOS:: +For instance, you may need to do something like: - $ TERMINFO_DIRS=/usr/share/terminfo + $ TERMINFO_DIRS=/uncommon/place/terminfo install/bin/python3.9 -e.g.:: +If you are running on a relatively standard OS and this does not work +out of the box, please file a bug report so we can add the location of +the *terminfo database* to the build. - $ TERMINFO_DIRS=/etc/terminfo:/lib/terminfo:/usr/share/terminfo install/bin/python3.9 - -The macOS distributions built with this project should automatically -use the terminfo database in ``/usr/share/terminfo``. Please file -a bug report if the macOS distributions do not behave as expected. - -Starting in the first release after 20240107, the Linux distributions are -configured to automatically use the terminfo database in ``/etc/terminfo``, -``/lib/terminfo``, and ``/usr/share/terminfo``. - -Also starting in the first release after 20240107, the terminfo database +For convenience, a relatively recent copy of the terminfo database is distributed in the ``share/terminfo`` directory (``../../share/terminfo`` relative to the ``bin/python3`` executable) in Linux distributions. Note that ncurses and derived libraries don't know how to find this directory @@ -109,33 +98,6 @@ To use pip, run ``python.exe -m pip``. (It is generally a best practice to invoke pip via ``python -m pip`` on all platforms so you can be explicit about the ``python`` executable that pip uses.) -.. _quirk_windows_static_distributions: - -Windows Static Distributions are Extremely Brittle -================================================== - -This project produces statically linked CPython distributions for Windows. - -Building these distributions requires extensive patching of CPython's build -system. There are many aspects of CPython, the standard library, and 3rd party -libraries that make assumptions that things will be built as dynamic libraries -and break in these static builds. - -Here is a list of known problems: - -* Most Windows extension modules link against ``pythonXY.dll`` (e.g. - ``python39.dll``) or ``python3.dll`` and will fail to load on the static - distributions. Extension modules will need to be explicitly recompiled - against the static distribution. -* There is no supported *platform tag* for Windows static distributions and - therefore there is no supported way to distribute binary wheels targeting - the Python static distributions. -* Aspects of OpenSSL (and therefore Python's ``ssl`` module) don't work when - OpenSSL is compiled/linked statically. You will get opaque run-time errors. - -It is **highly** recommended to extensively test your application against the -static Windows distributions to ensure it works. - .. _quirk_macos_linking: Linking Static Library on macOS @@ -177,29 +139,6 @@ Some functionality may behave subtly differently as a result of our choice to link ``libedit`` by default. (We choose ``libedit`` by default to avoid GPL licensing requirements of ``readline``.) -Static Linking of musl libc Prevents Extension Module Library Loading -===================================================================== - -Our musl libc linked Linux builds link musl libc statically and the resulting -binaries are completely static and don't have any external dependencies. - -Due to how Linux/ELF works, a static/non-dynamic binary cannot call -``dlopen()`` and therefore it cannot load shared library based Python -extension modules (``.so`` based extension modules). This significantly -limits the utility of these Python distributions. (If you want to use -additional extension modules you can use the build artifacts in the -distributions to construct a new ``libpython`` with the additional -extension modules configured as builtin extension modules.) - -Another consequence of statically linking musl libc is that our musl -distributions aren't compatible with -`PEP 656 `_. PEP 656 -stipulates that Python and extension modules are linked against a -dynamic musl. This is what you'll find in Alpine Linux, for example. - -See https://github.com/astral-sh/python-build-standalone/issues/86 for -a tracking issue to improve the state of musl distributions. - .. _quirk_linux_libx11: Static Linking of ``libX11`` / Incompatibility with PyQt on Linux @@ -259,40 +198,6 @@ And you can't easily remove ``_tkinter`` and its symbols from the pre-built and ready-to-use Python install included in this project's distribution artifacts. -.. _quirk_missing_libcrypt: - -Missing ``libcrypt.so.1`` -========================= - -Linux distributions in the 20230507 release and earlier had a hard dependency -on ``libcrypt.so.1`` due to static linking of the ``_crypt`` extension module, -which imports it. - -Presence of ``libcrypt.so.1`` is mandated as part of the Linux Standard Base -Core Specification and therefore should be present in Linux environments -conforming to this specification. Most Linux distributions historically -attempted to conform to this specification. - -In 2022, various Linux distributions stopped shipping ``libcrypt.so.1`` -(it appears glibc is ceasing to provide this functionality and Linux -distributions aren't backfilling ``libcrypt.so.1`` in the base install -to remain compatible with the Linux Standard Base Core Specification). - -In reaction to Linux distributions no longer providing ``libcrypt.so.1`` by -default, we changed the configuration of the ``_crypt`` extension module so -it is compiled/distributed as a standalone shared library and not compiled -into libpython. This means a missing ``libcrypt.so.1`` is only relevant if -the Python interpreter imports the ``crypt`` / ``_crypt`` modules. - -If you are using an older release of this project with a hard dependency -on ``libcrypt.so.1`` and don't want to upgrade, you can instruct end-users -to install a ``libxcrypt-compat`` (or comparable) package to provide the -missing ``libcrypt.so.1``. - -See https://github.com/astral-sh/python-build-standalone/issues/113 and -https://github.com/astral-sh/python-build-standalone/issues/173 for additional -context on this matter. - .. _quirk_references_to_build_paths: References to Build-Time Paths @@ -305,8 +210,8 @@ build-time configuration in a handful of files: ``lib/python3.10/_sysconfigdata__linux_x86_64-linux-gnu.py``. * In a ``Makefile`` under a ``config-*`` directory in the standard library. e.g. ``lib/python3.10/config-3.10-x86_64-linux-gnu/Makefile``. -* In ``python*-config`` files. e.g. ``bin/python3.10-config``. -* In ``PYTHON.json`` (mostly reflected values from ``_sysconfigdata_*.py``. +* In python-build-standalone's metadata file ``PYTHON.json`` (mostly + reflected values from ``_sysconfigdata_*.py``). Each of these serves a different use case. But the general theme is various aspects of the Python distribution attempt to capture how Python was built. @@ -317,47 +222,62 @@ module. ``sysconfig`` in turn is used by packaging tools like ``setuptools`` and ``pip`` to figure out how to invoke a compiler for e.g. compiling C extensions from source. -On Linux, our distributions are built in containers. The container has a -custom build of Clang in a custom filesystem location. And Python is -installed to the prefix ``/install``. So you may see references to -``/install`` in Linux distributions. - -On macOS, most distributions are built from GitHub Actions runners. They -use a specific macOS SDK. So you may see references to SDK paths that don't -exist on your machine. e.g. -``/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk``. - -On Windows, builds are performed from a temporary directory. So you may -see references to temporary directories in Windows distributions. - -**The existence of hard-coded paths in our produced distributions can confuse -consumers of these values and break common workflows, like compiling C -extensions.** - -We don't currently have a great idea for how to solve this problem. We -can't hardcode values that will work on every machine because every machine -has different filesystem layouts. For example, if we hardcode ``gcc`` as -the compiler, someone with only ``clang`` installed will complain. And -we certainly don't know where end-users will extract their Python -distribution to! - -To solve this problem requires executing dynamic code after extracting -our custom distributions in order to patch these hardcoded values into -conformance with the new machine. We're unsure how to actually do this -because figuring out what values to set is essentially equivalent to -reinventing autoconf / configure! Perhaps we could implement something -that works in common system layouts (e.g. hardcoded defaults for common -distros like Debian/Ubuntu and RedHat). - -Until we have a better solution here, just understand that anything looking -at ``sysconfig`` could resolve non-existent paths or names of binaries that -don't exist on the current machine. - -Starting with the Linux and macOS distributions released in 2024, we do -normalize some values in these files at build time. Normalizations include: - -* Removing compiler flags that are non-portable. -* Removing references to build paths (e.g. ``/tools`` on Linux). +When installed by `uv `_, these absolute +paths are fixed up to point to the actual location on your system where +the distribution was installed, so **this quirk generally does not +affect uv users**. The third-party tool `sysconfigpatcher +`_ also does this and might +be helpful to use or reference if you are installing these distributions +on your own. + +In particular, you may see references to our install-time paths on the +build infrastructure, e.g., ``/build`` and ``/install`` on Linux, a +particular SDK in ``/Applications/Xcode.app`` on macOS, and temporary +directories on Windows. + +Also, Python reports the compiler and flags in use, just in case it is +needed to make binary-compatible extensions. On Linux, for instance, we +use our own builds of Clang and potentially some flags (warnings, +optimizations, locations of the build environment) that do not work or +apply in other environments. We try to configure Python to remove +unneeded flags and absolute paths to files in the build environment. +references to build-time paths. Python's ``sysconfig`` system requires +listing a compiler, so we leave it set to ``clang`` without the absolute +path, but you should be able to use another compiler like ``gcc`` to +compile extensions, too. If there is a build time normalization that you think should be performed to make distributions more portable, please file a GitHub issue. + +.. _quirk_former: +.. _quirk_missing_libcrypt: + +Former quirks +============= + +The following quirks were previously listed on this page but have since +been resolved. + +* "Static Linking of musl libc Prevents Extension Module Library + Loading": Starting with the 20250311 release, the default musl + distributions are dynamically linked by default, so extension modules + should work properly. Note that these now require a system-wide + installation of the musl C library. (This is present by default on + musl-based OSes like Alpine, and many glibc-based distros have a + ``musl`` package you can safely co-install with glibc, too.) If you + specifically need a statically-linked binary, variants with the + ``+static`` build option are available, but these retain the quirk + that compiled extension modules (e.g., ``musllinux`` wheels) cannot be + loaded. + +* "Missing ``libcrypt.so.1``": The 20230507 release and earlier required + the system library ``libcrypt.so.1``, which stopped being shipped by + default in several Linux distributions around 2022. Starting with the + 20230726 release, this dependency is now only needed by the deprecated + ``crypt`` module, which only exists on Python 3.12 and lower. If you + still need this module, your OS may offer a ``libxcrypt`` package to + provide this library. Alternatively, there are suggestions in `What's + New in Python 3.13`_ about third-party replacements for the ``crypt`` + module. + +.. _What's New in Python 3.13: https://docs.python.org/3/whatsnew/3.13.html#whatsnew313-pep594 diff --git a/pythonbuild/cpython.py b/pythonbuild/cpython.py index e59eecd3..c52f7ce6 100644 --- a/pythonbuild/cpython.py +++ b/pythonbuild/cpython.py @@ -16,6 +16,19 @@ "properties": { "build-mode": {"type": "string"}, "config-c-only": {"type": "boolean"}, + "config-c-only-conditional": { + "type": "array", + "items": { + "type": "object", + "properties": { + "config-c-only": {"type": "boolean"}, + "minimum-python-version": {"type": "string"}, + "maximum-python-version": {"type": "string"}, + }, + "additionalProperties": False, + "required": ["config-c-only"], + }, + }, "defines": {"type": "array", "items": {"type": "string"}}, "defines-conditional": { "type": "array", @@ -286,6 +299,18 @@ def derive_setup_local( if info.get("config-c-only"): config_c_only_wanted.add(name) + for entry in info.get("config-c-only-conditional", []): + python_min_match_setup = meets_python_minimum_version( + python_version, entry.get("minimum-python-version", "1.0") + ) + python_max_match_setup = meets_python_maximum_version( + python_version, entry.get("maximum-python-version", "100.0") + ) + if entry.get("config-c-only", False) and ( + python_min_match_setup and python_max_match_setup + ): + config_c_only_wanted.add(name) + # Parse more files in the distribution for their metadata. with tarfile.open(str(cpython_source_archive)) as tf: @@ -647,7 +672,7 @@ def derive_setup_local( } -RE_INITTAB_ENTRY = re.compile('\{"([^"]+)", ([^\}]+)\},') +RE_INITTAB_ENTRY = re.compile(r'\{"([^"]+)", ([^\}]+)\},') def parse_config_c(s: str): diff --git a/pythonbuild/docker.py b/pythonbuild/docker.py index 4269b2bd..0be78e4f 100644 --- a/pythonbuild/docker.py +++ b/pythonbuild/docker.py @@ -29,8 +29,10 @@ def write_dockerfiles(source_dir: pathlib.Path, dest_dir: pathlib.Path): write_if_different(dest_dir / f, data.encode("utf-8")) -def build_docker_image(client, image_data: bytes, image_dir: pathlib.Path, name): - image_path = image_dir / ("image-%s" % name) +def build_docker_image( + client, image_data: bytes, image_dir: pathlib.Path, name, host_platform +): + image_path = image_dir / f"image-{name}.{host_platform}" return ensure_docker_image(client, io.BytesIO(image_data), image_path=image_path) @@ -66,11 +68,14 @@ def ensure_docker_image(client, fh, image_path=None): return image -def get_image(client, source_dir: pathlib.Path, image_dir: pathlib.Path, name): +def get_image( + client, source_dir: pathlib.Path, image_dir: pathlib.Path, name, host_platform +): if client is None: return None - image_path = image_dir / ("image-%s" % name) + image_name = f"image-{name}.{host_platform}" + image_path = image_dir / image_name tar_path = image_path.with_suffix(".tar") with image_path.open("r") as fh: @@ -88,7 +93,9 @@ def get_image(client, source_dir: pathlib.Path, image_dir: pathlib.Path, name): return image_id else: - return build_docker_image(client, str(source_dir).encode(), image_dir, name) + return build_docker_image( + client, str(source_dir).encode(), image_dir, name, host_platform + ) def copy_file_to_container(path, container, container_path, archive_path=None): diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py index 89f3ce08..24a9917e 100644 --- a/pythonbuild/downloads.py +++ b/pythonbuild/downloads.py @@ -37,55 +37,55 @@ "license_file": "LICENSE.bzip2.txt", }, "cpython-3.9": { - "url": "https://www.python.org/ftp/python/3.9.22/Python-3.9.22.tar.xz", - "size": 19652572, - "sha256": "8c136d199d3637a1fce98a16adc809c1d83c922d02d41f3614b34f8b6e7d38ec", - "version": "3.9.22", + "url": "https://www.python.org/ftp/python/3.9.23/Python-3.9.23.tar.xz", + "size": 19659284, + "sha256": "61a42919e13d539f7673cf11d1c404380e28e540510860b9d242196e165709c9", + "version": "3.9.23", "licenses": ["Python-2.0", "CNRI-Python"], "license_file": "LICENSE.cpython.txt", "python_tag": "cp39", }, "cpython-3.10": { - "url": "https://www.python.org/ftp/python/3.10.17/Python-3.10.17.tar.xz", - "size": 19608144, - "sha256": "4c68050f049d1b4ac5aadd0df5f27941c0350d2a9e7ab0907ee5eb5225d9d6b0", - "version": "3.10.17", + "url": "https://www.python.org/ftp/python/3.10.18/Python-3.10.18.tar.xz", + "size": 19619316, + "sha256": "ae665bc678abd9ab6a6e1573d2481625a53719bc517e9a634ed2b9fefae3817f", + "version": "3.10.18", "licenses": ["Python-2.0", "CNRI-Python"], "license_file": "LICENSE.cpython.txt", "python_tag": "cp310", }, "cpython-3.11": { - "url": "https://www.python.org/ftp/python/3.11.12/Python-3.11.12.tar.xz", - "size": 20112232, - "sha256": "849da87af4df137710c1796e276a955f7a85c9f971081067c8f565d15c352a09", - "version": "3.11.12", + "url": "https://www.python.org/ftp/python/3.11.13/Python-3.11.13.tar.xz", + "size": 20117496, + "sha256": "8fb5f9fbc7609fa822cb31549884575db7fd9657cbffb89510b5d7975963a83a", + "version": "3.11.13", "licenses": ["Python-2.0", "CNRI-Python"], "license_file": "LICENSE.cpython.txt", "python_tag": "cp311", }, "cpython-3.12": { - "url": "https://www.python.org/ftp/python/3.12.10/Python-3.12.10.tar.xz", - "size": 20520960, - "sha256": "07ab697474595e06f06647417d3c7fa97ded07afc1a7e4454c5639919b46eaea", - "version": "3.12.10", + "url": "https://www.python.org/ftp/python/3.12.11/Python-3.12.11.tar.xz", + "size": 20525812, + "sha256": "c30bb24b7f1e9a19b11b55a546434f74e739bb4c271a3e3a80ff4380d49f7adb", + "version": "3.12.11", "licenses": ["Python-2.0", "CNRI-Python"], "license_file": "LICENSE.cpython.txt", "python_tag": "cp312", }, "cpython-3.13": { - "url": "https://www.python.org/ftp/python/3.13.3/Python-3.13.3.tar.xz", - "size": 22654240, - "sha256": "40f868bcbdeb8149a3149580bb9bfd407b3321cd48f0be631af955ac92c0e041", - "version": "3.13.3", + "url": "https://www.python.org/ftp/python/3.13.5/Python-3.13.5.tar.xz", + "size": 22856016, + "sha256": "93e583f243454e6e9e4588ca2c2662206ad961659863277afcdb96801647d640", + "version": "3.13.5", "licenses": ["Python-2.0", "CNRI-Python"], "license_file": "LICENSE.cpython.txt", "python_tag": "cp313", }, "cpython-3.14": { - "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0a6.tar.xz", - "size": 22956068, - "sha256": "8d6181e5331d9a2cd6ca405ae1230e88589a043f4768ebb443d3889d45c1c35c", - "version": "3.14.0a6", + "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0b3.tar.xz", + "size": 23626928, + "sha256": "c6f48bf51f01f50d87007a445dd7afe4a4c7a87ab482570be924c1ddfd0d3682", + "version": "3.14.0b3", "licenses": ["Python-2.0", "CNRI-Python"], "license_file": "LICENSE.cpython.txt", "python_tag": "cp314", @@ -99,24 +99,12 @@ "licenses": ["MIT"], "license_file": "LICENSE.expat.txt", }, - "inputproto": { - "url": "https://www.x.org/archive/individual/proto/inputproto-2.3.2.tar.gz", - "size": 244334, - "sha256": "10eaadd531f38f7c92ab59ef0708ca195caf3164a75c4ed99f0c04f2913f6ef3", - "version": "2.3.2", - }, "jom-windows-bin": { "url": "http://download.qt.io/official_releases/jom/jom_1_1_4.zip", "size": 1696930, "sha256": "d533c1ef49214229681e90196ed2094691e8c4a0a0bef0b2c901debcb562682b", "version": "1.1.4", }, - "kbproto": { - "url": "https://www.x.org/archive/individual/proto/kbproto-1.0.7.tar.gz", - "size": 325858, - "sha256": "828cb275b91268b1a3ea950d5c0c5eb076c678fdf005d517411f89cc8c3bb416", - "version": "1.0.7", - }, "libedit": { "url": "https://thrysoee.dk/editline/libedit-20240808-3.1.tar.gz", "size": 538611, @@ -168,13 +156,11 @@ "licenses": ["MIT"], "license_file": "LICENSE.libXau.txt", }, - # Newer versions of libxcb require a modern Python to build. We can take this - # dependency once we feel like doing the work. "libxcb": { - "url": "https://xcb.freedesktop.org/dist/libxcb-1.14.tar.gz", - "size": 640322, - "sha256": "2c7fcddd1da34d9b238c9caeda20d3bd7486456fc50b3cc6567185dbd5b0ad02", - "version": "1.14", + "url": "https://xcb.freedesktop.org/dist/libxcb-1.17.0.tar.gz", + "size": 661593, + "sha256": "2c69287424c9e2128cb47ffe92171e10417041ec2963bceafb65cb3fcf8f0b85", + "version": "1.17.0", "library_names": ["xcb"], "licenses": ["MIT"], "license_file": "LICENSE.libxcb.txt", @@ -186,25 +172,32 @@ "version": "14.0.3+20220508", }, # Remember to update LLVM_URL in src/release.rs whenever upgrading. + "llvm-20-aarch64-linux": { + "url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-gnu_only-aarch64-unknown-linux-gnu.tar.zst", + "size": 255946687, + "sha256": "e70753f294b8f83fffbaf07af36857c27ceaef0291cb10f724ada6af11b0a5bc", + "version": "20.1.4+20250511", + }, + # Remember to update LLVM_URL in src/release.rs whenever upgrading. "llvm-20-x86_64-linux": { - "url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250308/llvm-20.1.0+20250308-gnu_only-x86_64-unknown-linux-gnu.tar.zst", - "size": 283261860, - "sha256": "41d3d74e21e064e2e59a4e89feca74d58a5e9e95f73877f3c9ed82ca95607b47", - "version": "20.1.0+20240308", + "url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-gnu_only-x86_64-unknown-linux-gnu.tar.zst", + "size": 299883811, + "sha256": "32374eb8b32fc79e9022f21eefc848d75fa3c46e68054a5dfc1f68d6f2f20429", + "version": "20.1.4+20250511", }, # Remember to update LLVM_URL in src/release.rs whenever upgrading. "llvm-aarch64-macos": { - "url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250308/llvm-20.1.0+20250308-aarch64-apple-darwin.tar.zst", - "size": 161006322, - "sha256": "9897bfaab16c930258f614250a1ade1a8f32df027181bd54a61d24b5a04e284c", - "version": "20.1.0+20240308", + "url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-aarch64-apple-darwin.tar.zst", + "size": 152858186, + "sha256": "d44bf8256b2468339c3b4491edb9c799ab89e466d98d098391286dc86e86a63b", + "version": "20.1.4+20250511", }, # Remember to update LLVM_URL in src/release.rs whenever upgrading. "llvm-x86_64-macos": { - "url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250308/llvm-20.1.0+20250308-x86_64-apple-darwin.tar.zst", - "size": 160133882, - "sha256": "95cfcb79d752e81735a7a7f7c4cb5a7c16360b6e9a75658a1bd50ce0547d4ad5", - "version": "20.1.0+20240308", + "url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-x86_64-apple-darwin.tar.zst", + "size": 160140682, + "sha256": "31b35734b678ad22471e31cf6a173c54819a3bca9ffefd4a70d8cdb935d67501", + "version": "20.1.4+20250511", }, "m4": { "url": "https://ftp.gnu.org/gnu/m4/m4-1.4.19.tar.xz", @@ -295,10 +288,10 @@ "license_file": "LICENSE.readline.txt", }, "setuptools": { - "url": "https://files.pythonhosted.org/packages/55/21/47d163f615df1d30c094f6c8bbb353619274edccf0327b185cc2493c2c33/setuptools-75.6.0-py3-none-any.whl", - "size": 1224032, - "sha256": "ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d", - "version": "75.6.0", + "url": "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", + "size": 1201486, + "sha256": "062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", + "version": "80.9.0", }, # Remember to update verify_distribution.py when version changed. "sqlite": { @@ -386,42 +379,28 @@ "license_file": "LICENSE.libuuid.txt", }, "x11-util-macros": { - "url": "https://www.x.org/archive/individual/util/util-macros-1.20.1.tar.gz", - "size": 105481, - "sha256": "b373f72887b1394ce2193180a60cb0d1fb8b17bc96ddd770cfd7a808cb489a15", - "version": "1.20.1", + "url": "https://www.x.org/archive/individual/util/util-macros-1.20.2.tar.gz", + "size": 105410, + "sha256": "f642f8964d81acdf06653fdf9dbc210c43ce4bd308bd644a8d573148d0ced76b", + "version": "1.20.2", }, "xcb-proto": { - "url": "https://www.x.org/archive/individual/proto/xcb-proto-1.14.1.tar.gz", - "size": 194674, - "sha256": "85cd21e9d9fbc341d0dbf11eace98d55d7db89fda724b0e598855fcddf0944fd", - "version": "1.14.1", - }, - "xextproto": { - "url": "https://www.x.org/archive/individual/proto/xextproto-7.3.0.tar.gz", - "size": 290814, - "sha256": "1b1bcdf91221e78c6c33738667a57bd9aaa63d5953174ad8ed9929296741c9f5", - "version": "7.3.0", - }, - # Newer versions from at least 2023 have build failures for reasons we haven't - # fully investigated. - "xorgproto": { - "url": "https://www.x.org/archive/individual/proto/xorgproto-2019.1.tar.gz", - "size": 1119813, - "sha256": "38ad1d8316515785d53c5162b4b7022918e03c11d72a5bd9df0a176607f42bca", - "version": "2019.1", + "url": "https://xcb.freedesktop.org/dist/xcb-proto-1.17.0.tar.xz", + "size": 151748, + "sha256": "2c1bacd2110f4799f74de6ebb714b94cf6f80fb112316b1219480fd22562148c", + "version": "1.17.0", }, - "xproto": { - "url": "https://www.x.org/archive/individual/proto/xproto-7.0.31.tar.gz", - "size": 367979, - "sha256": "6d755eaae27b45c5cc75529a12855fed5de5969b367ed05003944cf901ed43c7", - "version": "7.0.31", + "xorgproto": { + "url": "https://www.x.org/archive/individual/proto/xorgproto-2024.1.tar.gz", + "size": 1115486, + "sha256": "4f6b9b4faf91e5df8265b71843a91fc73dc895be6210c84117a996545df296ce", + "version": "2024.1", }, "xtrans": { - "url": "https://www.x.org/archive/individual/lib/xtrans-1.5.0.tar.gz", - "size": 230197, - "sha256": "a806f8a92f879dcd0146f3f1153fdffe845f2fc0df9b1a26c19312b7b0a29c86", - "version": "1.5.0", + "url": "https://www.x.org/archive/individual/lib/xtrans-1.6.0.tar.gz", + "size": 239113, + "sha256": "936b74c60b19c317c3f3cb1b114575032528dbdaf428740483200ea874c2ca0a", + "version": "1.6.0", }, # IMPORTANT: xz 5.6 has a backdoor. Be extremely cautious before taking any xz # upgrade since it isn't clear which versions are safe. @@ -446,4 +425,22 @@ "licenses": ["Zlib"], "license_file": "LICENSE.zlib.txt", }, + "zlib-ng": { + "url": "https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-ng-2.2.4.tar.gz", + "size": 2415819, + "sha256": "00bbd88709bc416cb96160ab61d3e1c8f76e106799af7328d0fe434dc7dd5004", + "version": "2.2.4", + "library_names": ["z"], + "licenses": ["Zlib"], + "license_file": "LICENSE.zlib-ng.txt", + }, + "zstd": { + "url": "https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz", + "size": 2440298, + "sha256": "f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e", + "version": "1.5.7", + "library_names": ["zstd"], + "licenses": ["BSD-3-Clause"], + "license_file": "LICENSE.zstd.txt", + }, } diff --git a/pythonbuild/utils.py b/pythonbuild/utils.py index 14d9a474..0edc11d7 100644 --- a/pythonbuild/utils.py +++ b/pythonbuild/utils.py @@ -30,6 +30,45 @@ from .logging import log +def current_host_platform() -> str: + """Resolve the name of the current machine's host platform. + + This is conceptually a simplified machine triple. + """ + machine = platform.machine() + if sys.platform == "linux": + if machine == "x86_64": + return "linux_x86_64" + elif machine == "aarch64": + return "linux_aarch64" + else: + raise Exception(f"unsupported Linux host platform: {machine}") + elif sys.platform == "darwin": + if machine == "arm64": + return "macos_arm64" + elif machine == "x86_64": + return "macos_x86_64" + else: + raise Exception(f"unhanded macOS machine type: {machine}") + else: + raise Exception(f"unsupported host platform: {sys.platform}") + + +def default_target_triple() -> str: + """Resolve the default target triple to build for.""" + host = current_host_platform() + if host == "linux_x86_64": + return "x86_64-unknown-linux-gnu" + elif host == "linux_aarch64": + return "aarch64-unknown-linux-gnu" + elif host == "macos_arm64": + return "aarch64-apple-darwin" + elif host == "macos_x86_64": + return "x86_64-apple-darwin" + else: + raise Exception(f"unrecognized host platform: {host}") + + def get_targets(yaml_path: pathlib.Path): """Obtain the parsed targets YAML file.""" with yaml_path.open("rb") as fh: @@ -47,9 +86,11 @@ def supported_targets(yaml_path: pathlib.Path): for target, settings in get_targets(yaml_path).items(): for host_platform in settings["host_platforms"]: - if sys.platform == "linux" and host_platform == "linux64": + if sys.platform == "linux" and host_platform == "linux_x86_64": + targets.add(target) + elif sys.platform == "linux" and host_platform == "linux_aarch64": targets.add(target) - elif sys.platform == "darwin" and host_platform == "macos": + elif sys.platform == "darwin" and host_platform.startswith("macos_"): targets.add(target) return targets @@ -159,8 +200,13 @@ def write_triples_makefiles( image_suffix = settings.get("docker_image_suffix", "") + # On cross builds, we can just use the bare `gcc` image + gcc_image_suffix = ( + image_suffix if not image_suffix.startswith(".cross") else "" + ) + lines.append("DOCKER_IMAGE_BUILD := build%s\n" % image_suffix) - lines.append("DOCKER_IMAGE_XCB := xcb%s\n" % image_suffix) + lines.append("DOCKER_IMAGE_GCC := gcc%s\n" % gcc_image_suffix) entry = clang_toolchain(host_platform, triple) lines.append( @@ -430,17 +476,18 @@ def sort_key(v): def clang_toolchain(host_platform: str, target_triple: str) -> str: - if host_platform == "linux64": + if host_platform == "linux_x86_64": # musl currently has issues with LLVM 15+. if "musl" in target_triple: return "llvm-14-x86_64-linux" else: return "llvm-20-x86_64-linux" - elif host_platform == "macos": - if platform.mac_ver()[2] == "arm64": - return "llvm-aarch64-macos" - else: - return "llvm-x86_64-macos" + elif host_platform == "linux_aarch64": + return "llvm-20-aarch64-linux" + elif host_platform == "macos_arm64": + return "llvm-aarch64-macos" + elif host_platform == "macos_x86_64": + return "llvm-x86_64-macos" else: raise Exception("unhandled host platform") @@ -537,17 +584,6 @@ def add_env_common(env): except FileNotFoundError: pass - # Proxy sccache settings. - for k, v in os.environ.items(): - if k.startswith("SCCACHE_"): - env[k] = v - - # Proxy cloud provider credentials variables to enable sccache to - # use stores in those providers. - for k in ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"): - if k in os.environ: - env[k] = os.environ[k] - def exec_and_log(args, cwd, env): p = subprocess.Popen( diff --git a/requirements.dev.txt b/requirements.dev.txt index dfeb2887..68171eb5 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -198,39 +198,48 @@ markupsafe==3.0.2 \ # via # -r requirements.txt # jinja2 -mypy==1.8.0 \ - --hash=sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6 \ - --hash=sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d \ - --hash=sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02 \ - --hash=sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d \ - --hash=sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3 \ - --hash=sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3 \ - --hash=sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3 \ - --hash=sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66 \ - --hash=sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259 \ - --hash=sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835 \ - --hash=sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd \ - --hash=sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d \ - --hash=sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8 \ - --hash=sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07 \ - --hash=sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b \ - --hash=sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e \ - --hash=sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6 \ - --hash=sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae \ - --hash=sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9 \ - --hash=sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d \ - --hash=sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a \ - --hash=sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592 \ - --hash=sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218 \ - --hash=sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817 \ - --hash=sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4 \ - --hash=sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410 \ - --hash=sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55 +mypy==1.16.0 \ + --hash=sha256:021a68568082c5b36e977d54e8f1de978baf401a33884ffcea09bd8e88a98f4c \ + --hash=sha256:089bedc02307c2548eb51f426e085546db1fa7dd87fbb7c9fa561575cf6eb1ff \ + --hash=sha256:09a8da6a0ee9a9770b8ff61b39c0bb07971cda90e7297f4213741b48a0cc8d93 \ + --hash=sha256:0b07e107affb9ee6ce1f342c07f51552d126c32cd62955f59a7db94a51ad12c0 \ + --hash=sha256:15486beea80be24ff067d7d0ede673b001d0d684d0095803b3e6e17a886a2a92 \ + --hash=sha256:29e1499864a3888bca5c1542f2d7232c6e586295183320caa95758fc84034031 \ + --hash=sha256:2e7e0ad35275e02797323a5aa1be0b14a4d03ffdb2e5f2b0489fa07b89c67b21 \ + --hash=sha256:4086883a73166631307fdd330c4a9080ce24913d4f4c5ec596c601b3a4bdd777 \ + --hash=sha256:54066fed302d83bf5128632d05b4ec68412e1f03ef2c300434057d66866cea4b \ + --hash=sha256:55f9076c6ce55dd3f8cd0c6fff26a008ca8e5131b89d5ba6d86bd3f47e736eeb \ + --hash=sha256:6a2322896003ba66bbd1318c10d3afdfe24e78ef12ea10e2acd985e9d684a666 \ + --hash=sha256:7909541fef256527e5ee9c0a7e2aeed78b6cda72ba44298d1334fe7881b05c5c \ + --hash=sha256:82d056e6faa508501af333a6af192c700b33e15865bda49611e3d7d8358ebea2 \ + --hash=sha256:84b94283f817e2aa6350a14b4a8fb2a35a53c286f97c9d30f53b63620e7af8ab \ + --hash=sha256:936ccfdd749af4766be824268bfe22d1db9eb2f34a3ea1d00ffbe5b5265f5491 \ + --hash=sha256:9f826aaa7ff8443bac6a494cf743f591488ea940dd360e7dd330e30dd772a5ab \ + --hash=sha256:a5fcfdb7318c6a8dd127b14b1052743b83e97a970f0edb6c913211507a255e20 \ + --hash=sha256:a7e32297a437cc915599e0578fa6bc68ae6a8dc059c9e009c628e1c47f91495d \ + --hash=sha256:a9e056237c89f1587a3be1a3a70a06a698d25e2479b9a2f57325ddaaffc3567b \ + --hash=sha256:afe420c9380ccec31e744e8baff0d406c846683681025db3531b32db56962d52 \ + --hash=sha256:b4968f14f44c62e2ec4a038c8797a87315be8df7740dc3ee8d3bfe1c6bf5dba8 \ + --hash=sha256:bd4e1ebe126152a7bbaa4daedd781c90c8f9643c79b9748caa270ad542f12bec \ + --hash=sha256:c5436d11e89a3ad16ce8afe752f0f373ae9620841c50883dc96f8b8805620b13 \ + --hash=sha256:c6fb60cbd85dc65d4d63d37cb5c86f4e3a301ec605f606ae3a9173e5cf34997b \ + --hash=sha256:d045d33c284e10a038f5e29faca055b90eee87da3fc63b8889085744ebabb5a1 \ + --hash=sha256:e71d6f0090c2256c713ed3d52711d01859c82608b5d68d4fa01a3fe30df95571 \ + --hash=sha256:eb14a4a871bb8efb1e4a50360d4e3c8d6c601e7a31028a2c79f9bb659b63d730 \ + --hash=sha256:eb5fbc8063cb4fde7787e4c0406aa63094a34a2daf4673f359a1fb64050e9cb2 \ + --hash=sha256:f2622af30bf01d8fc36466231bdd203d120d7a599a6d88fb22bdcb9dbff84090 \ + --hash=sha256:f2ed0e0847a80655afa2c121835b848ed101cc7b8d8d6ecc5205aedc732b1436 \ + --hash=sha256:f56236114c425620875c7cf71700e3d60004858da856c6fc78998ffe767b73d3 \ + --hash=sha256:feec38097f71797da0231997e0de3a58108c51845399669ebc532c815f93866b # via -r requirements.dev.in mypy-extensions==1.0.0 \ --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782 # via mypy +pathspec==0.12.1 \ + --hash=sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 \ + --hash=sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712 + # via mypy pyyaml==6.0.2 \ --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \ --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ @@ -408,24 +417,25 @@ rpds-py==0.22.3 \ # -r requirements.txt # jsonschema # referencing -ruff==0.3.4 \ - --hash=sha256:3f3860057590e810c7ffea75669bdc6927bfd91e29b4baa9258fd48b540a4365 \ - --hash=sha256:519cf6a0ebed244dce1dc8aecd3dc99add7a2ee15bb68cf19588bb5bf58e0488 \ - --hash=sha256:60c870a7d46efcbc8385d27ec07fe534ac32f3b251e4fc44b3cbfd9e09609ef4 \ - --hash=sha256:64abeed785dad51801b423fa51840b1764b35d6c461ea8caef9cf9e5e5ab34d9 \ - --hash=sha256:6810563cc08ad0096b57c717bd78aeac888a1bfd38654d9113cb3dc4d3f74232 \ - --hash=sha256:6fc14fa742e1d8f24910e1fff0bd5e26d395b0e0e04cc1b15c7c5e5fe5b4af91 \ - --hash=sha256:986f2377f7cf12efac1f515fc1a5b753c000ed1e0a6de96747cdf2da20a1b369 \ - --hash=sha256:98e98300056445ba2cc27d0b325fd044dc17fcc38e4e4d2c7711585bd0a958ed \ - --hash=sha256:af27ac187c0a331e8ef91d84bf1c3c6a5dea97e912a7560ac0cef25c526a4102 \ - --hash=sha256:bb0acfb921030d00070539c038cd24bb1df73a2981e9f55942514af8b17be94e \ - --hash=sha256:c4fd98e85869603e65f554fdc5cddf0712e352fe6e61d29d5a6fe087ec82b76c \ - --hash=sha256:cf133dd744f2470b347f602452a88e70dadfbe0fcfb5fd46e093d55da65f82f7 \ - --hash=sha256:cf187a7e7098233d0d0c71175375c5162f880126c4c716fa28a8ac418dcf3378 \ - --hash=sha256:d3ee7880f653cc03749a3bfea720cf2a192e4f884925b0cf7eecce82f0ce5854 \ - --hash=sha256:de0d5069b165e5a32b3c6ffbb81c350b1e3d3483347196ffdf86dc0ef9e37dd6 \ - --hash=sha256:df52972138318bc7546d92348a1ee58449bc3f9eaf0db278906eb511889c4b50 \ - --hash=sha256:f0f4484c6541a99862b693e13a151435a279b271cff20e37101116a21e2a1ad1 +ruff==0.11.13 \ + --hash=sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629 \ + --hash=sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432 \ + --hash=sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514 \ + --hash=sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3 \ + --hash=sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc \ + --hash=sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46 \ + --hash=sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9 \ + --hash=sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492 \ + --hash=sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b \ + --hash=sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165 \ + --hash=sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71 \ + --hash=sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc \ + --hash=sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250 \ + --hash=sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a \ + --hash=sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48 \ + --hash=sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b \ + --hash=sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7 \ + --hash=sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933 # via -r requirements.dev.in six==1.17.0 \ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ @@ -464,22 +474,24 @@ tomli==2.2.1 \ --hash=sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272 \ --hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \ --hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7 - # via -r requirements.txt + # via + # -r requirements.txt + # mypy types-jinja2==2.11.9 \ --hash=sha256:60a1e21e8296979db32f9374d8a239af4cb541ff66447bb915d8ad398f9c63b2 \ --hash=sha256:dbdc74a40aba7aed520b7e4d89e8f0fe4286518494208b35123bcf084d4b8c81 # via -r requirements.dev.in -types-jsonschema==4.21.0.20240118 \ - --hash=sha256:31aae1b5adc0176c1155c2d4f58348b22d92ae64315e9cc83bd6902168839232 \ - --hash=sha256:77a4ac36b0be4f24274d5b9bf0b66208ee771c05f80e34c4641de7d63e8a872d +types-jsonschema==4.24.0.20250528 \ + --hash=sha256:6a906b5ff73ac11c8d1e0b6c30a9693e1e4e1ab56c56c932b3a7e081b86d187b \ + --hash=sha256:7e28c64e0ae7980eeb158105b20663fc6a6b8f81d5f86ea6614aa0014417bd1e # via -r requirements.dev.in types-markupsafe==1.1.10 \ --hash=sha256:85b3a872683d02aea3a5ac2a8ef590193c344092032f58457287fbf8e06711b1 \ --hash=sha256:ca2bee0f4faafc45250602567ef38d533e877d2ddca13003b319c551ff5b3cc5 # via types-jinja2 -types-pyyaml==6.0.12.12 \ - --hash=sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062 \ - --hash=sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24 +types-pyyaml==6.0.12.20250516 \ + --hash=sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530 \ + --hash=sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba # via -r requirements.dev.in typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ diff --git a/requirements.in b/requirements.in index a6753f74..0e9ae39a 100644 --- a/requirements.in +++ b/requirements.in @@ -7,4 +7,5 @@ six # This is a transitive dependency that doesn't get picked up when running on # modern Python. So include to force it in requirements.txt. tomli +typing-extensions zstandard diff --git a/requirements.win.txt b/requirements.win.txt index aa1a25c6..d37a96ff 100644 --- a/requirements.win.txt +++ b/requirements.win.txt @@ -1,212 +1,209 @@ # This file was autogenerated by uv via the following command: # uv pip compile --python-platform windows --generate-hashes requirements.in -o requirements.win.txt -attrs==23.2.0 \ - --hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \ - --hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1 +attrs==25.3.0 \ + --hash=sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3 \ + --hash=sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b # via # jsonschema # referencing -certifi==2024.2.2 \ - --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \ - --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 +certifi==2025.4.26 \ + --hash=sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6 \ + --hash=sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3 # via requests -charset-normalizer==3.3.2 \ - --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ - --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ - --hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \ - --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \ - --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \ - --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \ - --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \ - --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \ - --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \ - --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \ - --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \ - --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \ - --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \ - --hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \ - --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \ - --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \ - --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \ - --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ - --hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \ - --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \ - --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \ - --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \ - --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \ - --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \ - --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \ - --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \ - --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \ - --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \ - --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \ - --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \ - --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \ - --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \ - --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \ - --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \ - --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \ - --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \ - --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \ - --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \ - --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \ - --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \ - --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \ - --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \ - --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \ - --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \ - --hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \ - --hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \ - --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \ - --hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \ - --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \ - --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \ - --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \ - --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \ - --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \ - --hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \ - --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ - --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \ - --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \ - --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \ - --hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \ - --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \ - --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \ - --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \ - --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \ - --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \ - --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \ - --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \ - --hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \ - --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \ - --hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \ - --hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \ - --hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \ - --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \ - --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \ - --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \ - --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \ - --hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \ - --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \ - --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \ - --hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \ - --hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \ - --hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \ - --hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \ - --hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \ - --hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \ - --hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \ - --hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \ - --hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \ - --hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \ - --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ - --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 +charset-normalizer==3.4.2 \ + --hash=sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4 \ + --hash=sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45 \ + --hash=sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7 \ + --hash=sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0 \ + --hash=sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7 \ + --hash=sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d \ + --hash=sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d \ + --hash=sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0 \ + --hash=sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184 \ + --hash=sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db \ + --hash=sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b \ + --hash=sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64 \ + --hash=sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b \ + --hash=sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8 \ + --hash=sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff \ + --hash=sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344 \ + --hash=sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58 \ + --hash=sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e \ + --hash=sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471 \ + --hash=sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148 \ + --hash=sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a \ + --hash=sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836 \ + --hash=sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e \ + --hash=sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63 \ + --hash=sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c \ + --hash=sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1 \ + --hash=sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01 \ + --hash=sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366 \ + --hash=sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58 \ + --hash=sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5 \ + --hash=sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c \ + --hash=sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2 \ + --hash=sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a \ + --hash=sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597 \ + --hash=sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b \ + --hash=sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5 \ + --hash=sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb \ + --hash=sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f \ + --hash=sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0 \ + --hash=sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941 \ + --hash=sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0 \ + --hash=sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86 \ + --hash=sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7 \ + --hash=sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7 \ + --hash=sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455 \ + --hash=sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6 \ + --hash=sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4 \ + --hash=sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0 \ + --hash=sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3 \ + --hash=sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1 \ + --hash=sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6 \ + --hash=sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981 \ + --hash=sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c \ + --hash=sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980 \ + --hash=sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645 \ + --hash=sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7 \ + --hash=sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12 \ + --hash=sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa \ + --hash=sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd \ + --hash=sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef \ + --hash=sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f \ + --hash=sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2 \ + --hash=sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d \ + --hash=sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5 \ + --hash=sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02 \ + --hash=sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3 \ + --hash=sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd \ + --hash=sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e \ + --hash=sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214 \ + --hash=sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd \ + --hash=sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a \ + --hash=sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c \ + --hash=sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681 \ + --hash=sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba \ + --hash=sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f \ + --hash=sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a \ + --hash=sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28 \ + --hash=sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691 \ + --hash=sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82 \ + --hash=sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a \ + --hash=sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027 \ + --hash=sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7 \ + --hash=sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518 \ + --hash=sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf \ + --hash=sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b \ + --hash=sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9 \ + --hash=sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544 \ + --hash=sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da \ + --hash=sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509 \ + --hash=sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f \ + --hash=sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a \ + --hash=sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f # via requests -docker==7.0.0 \ - --hash=sha256:12ba681f2777a0ad28ffbcc846a69c31b4dfd9752b47eb425a274ee269c5e14b \ - --hash=sha256:323736fb92cd9418fc5e7133bc953e11a9da04f4483f828b527db553f1e7e5a3 +docker==7.1.0 \ + --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \ + --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0 # via -r requirements.in -idna==3.6 \ - --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ - --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f +idna==3.10 \ + --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ + --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 # via requests -jinja2==3.1.3 \ - --hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \ - --hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90 +jinja2==3.1.6 \ + --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ + --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # via -r requirements.in -jsonschema==4.21.1 \ - --hash=sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f \ - --hash=sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5 +jsonschema==4.24.0 \ + --hash=sha256:0b4e8069eb12aedfa881333004bccaec24ecef5a8a6a4b6df142b2cc9599d196 \ + --hash=sha256:a462455f19f5faf404a7902952b6f0e3ce868f3ee09a359b05eca6673bd8412d # via -r requirements.in -jsonschema-specifications==2023.12.1 \ - --hash=sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc \ - --hash=sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c +jsonschema-specifications==2025.4.1 \ + --hash=sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af \ + --hash=sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608 # via jsonschema -markupsafe==2.1.5 \ - --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ - --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ - --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ - --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ - --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ - --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ - --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ - --hash=sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df \ - --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ - --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ - --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ - --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ - --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ - --hash=sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371 \ - --hash=sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2 \ - --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ - --hash=sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52 \ - --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ - --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ - --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ - --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ - --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ - --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ - --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ - --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ - --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ - --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ - --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ - --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ - --hash=sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9 \ - --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ - --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ - --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ - --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ - --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ - --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ - --hash=sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a \ - --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ - --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ - --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ - --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ - --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ - --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ - --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ - --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ - --hash=sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f \ - --hash=sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50 \ - --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ - --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ - --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ - --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ - --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ - --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ - --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ - --hash=sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf \ - --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ - --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ - --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ - --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ - --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 +markupsafe==3.0.2 \ + --hash=sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4 \ + --hash=sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30 \ + --hash=sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0 \ + --hash=sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9 \ + --hash=sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 \ + --hash=sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13 \ + --hash=sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028 \ + --hash=sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca \ + --hash=sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557 \ + --hash=sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832 \ + --hash=sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0 \ + --hash=sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b \ + --hash=sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579 \ + --hash=sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a \ + --hash=sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c \ + --hash=sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff \ + --hash=sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c \ + --hash=sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22 \ + --hash=sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094 \ + --hash=sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb \ + --hash=sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e \ + --hash=sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5 \ + --hash=sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a \ + --hash=sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d \ + --hash=sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a \ + --hash=sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b \ + --hash=sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8 \ + --hash=sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225 \ + --hash=sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c \ + --hash=sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144 \ + --hash=sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f \ + --hash=sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87 \ + --hash=sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d \ + --hash=sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93 \ + --hash=sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf \ + --hash=sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158 \ + --hash=sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84 \ + --hash=sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb \ + --hash=sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48 \ + --hash=sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171 \ + --hash=sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c \ + --hash=sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6 \ + --hash=sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd \ + --hash=sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d \ + --hash=sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1 \ + --hash=sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d \ + --hash=sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca \ + --hash=sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a \ + --hash=sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29 \ + --hash=sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe \ + --hash=sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798 \ + --hash=sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c \ + --hash=sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8 \ + --hash=sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f \ + --hash=sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f \ + --hash=sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a \ + --hash=sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178 \ + --hash=sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0 \ + --hash=sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79 \ + --hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \ + --hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50 # via jinja2 -packaging==23.2 \ - --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \ - --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7 - # via docker -pywin32==308 \ - --hash=sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47 \ - --hash=sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6 \ - --hash=sha256:13dcb914ed4347019fbec6697a01a0aec61019c1046c2b905410d197856326a6 \ - --hash=sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed \ - --hash=sha256:1f696ab352a2ddd63bd07430080dd598e6369152ea13a25ebcdd2f503a38f1ff \ - --hash=sha256:3b92622e29d651c6b783e368ba7d6722b1634b8e70bd376fd7610fe1992e19de \ - --hash=sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e \ - --hash=sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b \ - --hash=sha256:5794e764ebcabf4ff08c555b31bd348c9025929371763b2183172ff4708152f0 \ - --hash=sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897 \ - --hash=sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a \ - --hash=sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920 \ - --hash=sha256:7873ca4dc60ab3287919881a7d4f88baee4a6e639aa6962de25a98ba6b193341 \ - --hash=sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e \ - --hash=sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091 \ - --hash=sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c \ - --hash=sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd \ - --hash=sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4 +pywin32==310 \ + --hash=sha256:0867beb8addefa2e3979d4084352e4ac6e991ca45373390775f7084cc0209b9c \ + --hash=sha256:126298077a9d7c95c53823934f000599f66ec9296b09167810eb24875f32689c \ + --hash=sha256:19ec5fc9b1d51c4350be7bb00760ffce46e6c95eaf2f0b2f1150657b1a43c582 \ + --hash=sha256:1e765f9564e83011a63321bb9d27ec456a0ed90d3732c4b2e312b855365ed8bd \ + --hash=sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966 \ + --hash=sha256:30f0a9b3138fb5e07eb4973b7077e1883f558e40c578c6925acc7a94c34eaa36 \ + --hash=sha256:33babed0cf0c92a6f94cc6cc13546ab24ee13e3e800e61ed87609ab91e4c8213 \ + --hash=sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab \ + --hash=sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e \ + --hash=sha256:6dd97011efc8bf51d6793a82292419eba2c71cf8e7250cfac03bba284454abc1 \ + --hash=sha256:851c8d927af0d879221e616ae1f66145253537bbdd321a77e8ef701b443a9a1a \ + --hash=sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d \ + --hash=sha256:96867217335559ac619f00ad70e513c0fcf84b8a3af9fc2bba3b59b97da70475 \ + --hash=sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060 \ + --hash=sha256:c3e78706e4229b915a0821941a84e7ef420bf2b77e08c9dae3c76fd03fd2ae3d \ + --hash=sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33 # via docker pyyaml==6.0.1 \ --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ @@ -261,178 +258,281 @@ pyyaml==6.0.1 \ --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f # via -r requirements.in -referencing==0.33.0 \ - --hash=sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5 \ - --hash=sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7 +referencing==0.36.2 \ + --hash=sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa \ + --hash=sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0 # via # jsonschema # jsonschema-specifications -requests==2.31.0 \ - --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ - --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 +requests==2.32.4 \ + --hash=sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c \ + --hash=sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422 # via docker -rpds-py==0.18.0 \ - --hash=sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f \ - --hash=sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c \ - --hash=sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76 \ - --hash=sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e \ - --hash=sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157 \ - --hash=sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f \ - --hash=sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5 \ - --hash=sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05 \ - --hash=sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24 \ - --hash=sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1 \ - --hash=sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8 \ - --hash=sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b \ - --hash=sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb \ - --hash=sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07 \ - --hash=sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1 \ - --hash=sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6 \ - --hash=sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e \ - --hash=sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e \ - --hash=sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1 \ - --hash=sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab \ - --hash=sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4 \ - --hash=sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17 \ - --hash=sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594 \ - --hash=sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d \ - --hash=sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d \ - --hash=sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3 \ - --hash=sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c \ - --hash=sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66 \ - --hash=sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f \ - --hash=sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80 \ - --hash=sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33 \ - --hash=sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f \ - --hash=sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c \ - --hash=sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022 \ - --hash=sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e \ - --hash=sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f \ - --hash=sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da \ - --hash=sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1 \ - --hash=sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688 \ - --hash=sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795 \ - --hash=sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c \ - --hash=sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98 \ - --hash=sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1 \ - --hash=sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20 \ - --hash=sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307 \ - --hash=sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4 \ - --hash=sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18 \ - --hash=sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294 \ - --hash=sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66 \ - --hash=sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467 \ - --hash=sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948 \ - --hash=sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e \ - --hash=sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1 \ - --hash=sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0 \ - --hash=sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7 \ - --hash=sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd \ - --hash=sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641 \ - --hash=sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d \ - --hash=sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9 \ - --hash=sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1 \ - --hash=sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da \ - --hash=sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3 \ - --hash=sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa \ - --hash=sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7 \ - --hash=sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40 \ - --hash=sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496 \ - --hash=sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124 \ - --hash=sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836 \ - --hash=sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434 \ - --hash=sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984 \ - --hash=sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f \ - --hash=sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6 \ - --hash=sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e \ - --hash=sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461 \ - --hash=sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c \ - --hash=sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432 \ - --hash=sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73 \ - --hash=sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58 \ - --hash=sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88 \ - --hash=sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337 \ - --hash=sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7 \ - --hash=sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863 \ - --hash=sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475 \ - --hash=sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3 \ - --hash=sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51 \ - --hash=sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf \ - --hash=sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024 \ - --hash=sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40 \ - --hash=sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9 \ - --hash=sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec \ - --hash=sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb \ - --hash=sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7 \ - --hash=sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861 \ - --hash=sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880 \ - --hash=sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f \ - --hash=sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd \ - --hash=sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca \ - --hash=sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58 \ - --hash=sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e +rpds-py==0.25.1 \ + --hash=sha256:0317177b1e8691ab5879f4f33f4b6dc55ad3b344399e23df2e499de7b10a548d \ + --hash=sha256:036ded36bedb727beeabc16dc1dad7cb154b3fa444e936a03b67a86dc6a5066e \ + --hash=sha256:048893e902132fd6548a2e661fb38bf4896a89eea95ac5816cf443524a85556f \ + --hash=sha256:0701942049095741a8aeb298a31b203e735d1c61f4423511d2b1a41dcd8a16da \ + --hash=sha256:083a9513a33e0b92cf6e7a6366036c6bb43ea595332c1ab5c8ae329e4bcc0a9c \ + --hash=sha256:09eab132f41bf792c7a0ea1578e55df3f3e7f61888e340779b06050a9a3f16e9 \ + --hash=sha256:0e6a327af8ebf6baba1c10fadd04964c1965d375d318f4435d5f3f9651550f4a \ + --hash=sha256:0eb90e94f43e5085623932b68840b6f379f26db7b5c2e6bcef3179bd83c9330f \ + --hash=sha256:114a07e85f32b125404f28f2ed0ba431685151c037a26032b213c882f26eb908 \ + --hash=sha256:115874ae5e2fdcfc16b2aedc95b5eef4aebe91b28e7e21951eda8a5dc0d3461b \ + --hash=sha256:140f61d9bed7839446bdd44852e30195c8e520f81329b4201ceead4d64eb3a9f \ + --hash=sha256:1521031351865e0181bc585147624d66b3b00a84109b57fcb7a779c3ec3772cd \ + --hash=sha256:1c0c434a53714358532d13539272db75a5ed9df75a4a090a753ac7173ec14e11 \ + --hash=sha256:1d1fadd539298e70cac2f2cb36f5b8a65f742b9b9f1014dd4ea1f7785e2470bf \ + --hash=sha256:1de336a4b164c9188cb23f3703adb74a7623ab32d20090d0e9bf499a2203ad65 \ + --hash=sha256:1ee3e26eb83d39b886d2cb6e06ea701bba82ef30a0de044d34626ede51ec98b0 \ + --hash=sha256:245550f5a1ac98504147cba96ffec8fabc22b610742e9150138e5d60774686d7 \ + --hash=sha256:2a40046a529cc15cef88ac5ab589f83f739e2d332cb4d7399072242400ed68c9 \ + --hash=sha256:2c2cd1a4b0c2b8c5e31ffff50d09f39906fe351389ba143c195566056c13a7ea \ + --hash=sha256:2cb9e5b5e26fc02c8a4345048cd9998c2aca7c2712bd1b36da0c72ee969a3523 \ + --hash=sha256:33358883a4490287e67a2c391dfaea4d9359860281db3292b6886bf0be3d8692 \ + --hash=sha256:35634369325906bcd01577da4c19e3b9541a15e99f31e91a02d010816b49bfda \ + --hash=sha256:35a8d1a24b5936b35c5003313bc177403d8bdef0f8b24f28b1c4a255f94ea992 \ + --hash=sha256:3af5b4cc10fa41e5bc64e5c198a1b2d2864337f8fcbb9a67e747e34002ce812b \ + --hash=sha256:3bcce0edc1488906c2d4c75c94c70a0417e83920dd4c88fec1078c94843a6ce9 \ + --hash=sha256:3c5b317ecbd8226887994852e85de562f7177add602514d4ac40f87de3ae45a8 \ + --hash=sha256:3c6564c0947a7f52e4792983f8e6cf9bac140438ebf81f527a21d944f2fd0a40 \ + --hash=sha256:3ebd879ab996537fc510a2be58c59915b5dd63bccb06d1ef514fee787e05984a \ + --hash=sha256:3f0b1798cae2bbbc9b9db44ee068c556d4737911ad53a4e5093d09d04b3bbc24 \ + --hash=sha256:401ca1c4a20cc0510d3435d89c069fe0a9ae2ee6495135ac46bdd49ec0495763 \ + --hash=sha256:454601988aab2c6e8fd49e7634c65476b2b919647626208e376afcd22019eeb8 \ + --hash=sha256:4593c4eae9b27d22df41cde518b4b9e4464d139e4322e2127daa9b5b981b76be \ + --hash=sha256:45e484db65e5380804afbec784522de84fa95e6bb92ef1bd3325d33d13efaebd \ + --hash=sha256:48d64155d02127c249695abb87d39f0faf410733428d499867606be138161d65 \ + --hash=sha256:4fbb0dbba559959fcb5d0735a0f87cdbca9e95dac87982e9b95c0f8f7ad10255 \ + --hash=sha256:4fd52d3455a0aa997734f3835cbc4c9f32571345143960e7d7ebfe7b5fbfa3b2 \ + --hash=sha256:50f2c501a89c9a5f4e454b126193c5495b9fb441a75b298c60591d8a2eb92e1b \ + --hash=sha256:58f77c60956501a4a627749a6dcb78dac522f249dd96b5c9f1c6af29bfacfb66 \ + --hash=sha256:5a3ddb74b0985c4387719fc536faced33cadf2172769540c62e2a94b7b9be1c4 \ + --hash=sha256:5c4a128527fe415d73cf1f70a9a688d06130d5810be69f3b553bf7b45e8acf79 \ + --hash=sha256:5d473be2b13600b93a5675d78f59e63b51b1ba2d0476893415dfbb5477e65b31 \ + --hash=sha256:5d9e40f32745db28c1ef7aad23f6fc458dc1e29945bd6781060f0d15628b8ddf \ + --hash=sha256:5f048bbf18b1f9120685c6d6bb70cc1a52c8cc11bdd04e643d28d3be0baf666d \ + --hash=sha256:605ffe7769e24b1800b4d024d24034405d9404f0bc2f55b6db3362cd34145a6f \ + --hash=sha256:6099263f526efff9cf3883dfef505518730f7a7a93049b1d90d42e50a22b4793 \ + --hash=sha256:659d87430a8c8c704d52d094f5ba6fa72ef13b4d385b7e542a08fc240cb4a559 \ + --hash=sha256:666fa7b1bd0a3810a7f18f6d3a25ccd8866291fbbc3c9b912b917a6715874bb9 \ + --hash=sha256:68f6f060f0bbdfb0245267da014d3a6da9be127fe3e8cc4a68c6f833f8a23bb1 \ + --hash=sha256:6d273f136e912aa101a9274c3145dcbddbe4bac560e77e6d5b3c9f6e0ed06d34 \ + --hash=sha256:6d50841c425d16faf3206ddbba44c21aa3310a0cebc3c1cdfc3e3f4f9f6f5728 \ + --hash=sha256:771c16060ff4e79584dc48902a91ba79fd93eade3aa3a12d6d2a4aadaf7d542b \ + --hash=sha256:785ffacd0ee61c3e60bdfde93baa6d7c10d86f15655bd706c89da08068dc5038 \ + --hash=sha256:796ad874c89127c91970652a4ee8b00d56368b7e00d3477f4415fe78164c8000 \ + --hash=sha256:79dc317a5f1c51fd9c6a0c4f48209c6b8526d0524a6904fc1076476e79b00f98 \ + --hash=sha256:7c9409b47ba0650544b0bb3c188243b83654dfe55dcc173a86832314e1a6a35d \ + --hash=sha256:7d779b325cc8238227c47fbc53964c8cc9a941d5dbae87aa007a1f08f2f77b23 \ + --hash=sha256:816568614ecb22b18a010c7a12559c19f6fe993526af88e95a76d5a60b8b75fb \ + --hash=sha256:8378fa4a940f3fb509c081e06cb7f7f2adae8cf46ef258b0e0ed7519facd573e \ + --hash=sha256:85608eb70a659bf4c1142b2781083d4b7c0c4e2c90eff11856a9754e965b2540 \ + --hash=sha256:85fc223d9c76cabe5d0bff82214459189720dc135db45f9f66aa7cffbf9ff6c1 \ + --hash=sha256:88ec04afe0c59fa64e2f6ea0dd9657e04fc83e38de90f6de201954b4d4eb59bd \ + --hash=sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3 \ + --hash=sha256:89706d0683c73a26f76a5315d893c051324d771196ae8b13e6ffa1ffaf5e574f \ + --hash=sha256:89c24300cd4a8e4a51e55c31a8ff3918e6651b241ee8876a42cc2b2a078533ba \ + --hash=sha256:8c742af695f7525e559c16f1562cf2323db0e3f0fbdcabdf6865b095256b2d40 \ + --hash=sha256:8dbd586bfa270c1103ece2109314dd423df1fa3d9719928b5d09e4840cec0d72 \ + --hash=sha256:8eb8c84ecea987a2523e057c0d950bcb3f789696c0499290b8d7b3107a719d78 \ + --hash=sha256:921954d7fbf3fccc7de8f717799304b14b6d9a45bbeec5a8d7408ccbf531faf5 \ + --hash=sha256:9a46c2fb2545e21181445515960006e85d22025bd2fe6db23e76daec6eb689fe \ + --hash=sha256:9c006f3aadeda131b438c3092124bd196b66312f0caa5823ef09585a669cf449 \ + --hash=sha256:9ceca1cf097ed77e1a51f1dbc8d174d10cb5931c188a4505ff9f3e119dfe519b \ + --hash=sha256:9e5fc7484fa7dce57e25063b0ec9638ff02a908304f861d81ea49273e43838c1 \ + --hash=sha256:9f2f48ab00181600ee266a095fe815134eb456163f7d6699f525dee471f312cf \ + --hash=sha256:9fca84a15333e925dd59ce01da0ffe2ffe0d6e5d29a9eeba2148916d1824948c \ + --hash=sha256:a49e1d7a4978ed554f095430b89ecc23f42014a50ac385eb0c4d163ce213c325 \ + --hash=sha256:a58d1ed49a94d4183483a3ce0af22f20318d4a1434acee255d683ad90bf78129 \ + --hash=sha256:a61d0b2c7c9a0ae45732a77844917b427ff16ad5464b4d4f5e4adb955f582890 \ + --hash=sha256:a714bf6e5e81b0e570d01f56e0c89c6375101b8463999ead3a93a5d2a4af91fa \ + --hash=sha256:a7b74e92a3b212390bdce1d93da9f6488c3878c1d434c5e751cbc202c5e09500 \ + --hash=sha256:a8bd2f19e312ce3e1d2c635618e8a8d8132892bb746a7cf74780a489f0f6cdcb \ + --hash=sha256:b0be9965f93c222fb9b4cc254235b3b2b215796c03ef5ee64f995b1b69af0762 \ + --hash=sha256:b24bf3cd93d5b6ecfbedec73b15f143596c88ee249fa98cefa9a9dc9d92c6f28 \ + --hash=sha256:b5ffe453cde61f73fea9430223c81d29e2fbf412a6073951102146c84e19e34c \ + --hash=sha256:bc120d1132cff853ff617754196d0ac0ae63befe7c8498bd67731ba368abe451 \ + --hash=sha256:bd035756830c712b64725a76327ce80e82ed12ebab361d3a1cdc0f51ea21acb0 \ + --hash=sha256:bffcf57826d77a4151962bf1701374e0fc87f536e56ec46f1abdd6a903354042 \ + --hash=sha256:c2013ee878c76269c7b557a9a9c042335d732e89d482606990b70a839635feb7 \ + --hash=sha256:c4feb9211d15d9160bc85fa72fed46432cdc143eb9cf6d5ca377335a921ac37b \ + --hash=sha256:c8980cde3bb8575e7c956a530f2c217c1d6aac453474bf3ea0f9c89868b531b6 \ + --hash=sha256:c98f126c4fc697b84c423e387337d5b07e4a61e9feac494362a59fd7a2d9ed80 \ + --hash=sha256:ccc6f3ddef93243538be76f8e47045b4aad7a66a212cd3a0f23e34469473d36b \ + --hash=sha256:ccfa689b9246c48947d31dd9d8b16d89a0ecc8e0e26ea5253068efb6c542b76e \ + --hash=sha256:cda776f1967cb304816173b30994faaf2fd5bcb37e73118a47964a02c348e1bc \ + --hash=sha256:ce4c8e485a3c59593f1a6f683cf0ea5ab1c1dc94d11eea5619e4fb5228b40fbd \ + --hash=sha256:d3c10228d6cf6fe2b63d2e7985e94f6916fa46940df46b70449e9ff9297bd3d1 \ + --hash=sha256:d4ca54b9cf9d80b4016a67a0193ebe0bcf29f6b0a96f09db942087e294d3d4c2 \ + --hash=sha256:d4cb2b3ddc16710548801c6fcc0cfcdeeff9dafbc983f77265877793f2660309 \ + --hash=sha256:d50e4864498a9ab639d6d8854b25e80642bd362ff104312d9770b05d66e5fb13 \ + --hash=sha256:d74ec9bc0e2feb81d3f16946b005748119c0f52a153f6db6a29e8cd68636f295 \ + --hash=sha256:d8222acdb51a22929c3b2ddb236b69c59c72af4019d2cba961e2f9add9b6e634 \ + --hash=sha256:db58483f71c5db67d643857404da360dce3573031586034b7d59f245144cc192 \ + --hash=sha256:dc3c1ff0abc91444cd20ec643d0f805df9a3661fcacf9c95000329f3ddf268a4 \ + --hash=sha256:dd326a81afe332ede08eb39ab75b301d5676802cdffd3a8f287a5f0b694dc3f5 \ + --hash=sha256:dec21e02e6cc932538b5203d3a8bd6aa1480c98c4914cb88eea064ecdbc6396a \ + --hash=sha256:e1dafef8df605fdb46edcc0bf1573dea0d6d7b01ba87f85cd04dc855b2b4479e \ + --hash=sha256:e2f6a2347d3440ae789505693a02836383426249d5293541cd712e07e7aecf54 \ + --hash=sha256:e37caa8cdb3b7cf24786451a0bdb853f6347b8b92005eeb64225ae1db54d1c2b \ + --hash=sha256:e43a005671a9ed5a650f3bc39e4dbccd6d4326b24fb5ea8be5f3a43a6f576c72 \ + --hash=sha256:e5e2f7280d8d0d3ef06f3ec1b4fd598d386cc6f0721e54f09109a8132182fbfe \ + --hash=sha256:e87798852ae0b37c88babb7f7bbbb3e3fecc562a1c340195b44c7e24d403e380 \ + --hash=sha256:ee86d81551ec68a5c25373c5643d343150cc54672b5e9a0cafc93c1870a53954 \ + --hash=sha256:f251bf23deb8332823aef1da169d5d89fa84c89f67bdfb566c49dea1fccfd50d \ + --hash=sha256:f3d86373ff19ca0441ebeb696ef64cb58b8b5cbacffcda5a0ec2f3911732a194 \ + --hash=sha256:f4ad628b5174d5315761b67f212774a32f5bad5e61396d38108bd801c0a8f5d9 \ + --hash=sha256:f70316f760174ca04492b5ab01be631a8ae30cadab1d1081035136ba12738cfa \ + --hash=sha256:f73ce1512e04fbe2bc97836e89830d6b4314c171587a99688082d090f934d20a \ + --hash=sha256:ff7c23ba0a88cb7b104281a99476cccadf29de2a0ef5ce864959a52675b1ca83 # via # jsonschema # referencing -six==1.16.0 \ - --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ - --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 +six==1.17.0 \ + --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ + --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 + # via -r requirements.in +tomli==2.2.1 \ + --hash=sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6 \ + --hash=sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd \ + --hash=sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c \ + --hash=sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b \ + --hash=sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8 \ + --hash=sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6 \ + --hash=sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77 \ + --hash=sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff \ + --hash=sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea \ + --hash=sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192 \ + --hash=sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249 \ + --hash=sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee \ + --hash=sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4 \ + --hash=sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98 \ + --hash=sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8 \ + --hash=sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4 \ + --hash=sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281 \ + --hash=sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744 \ + --hash=sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69 \ + --hash=sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13 \ + --hash=sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140 \ + --hash=sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e \ + --hash=sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e \ + --hash=sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc \ + --hash=sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff \ + --hash=sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec \ + --hash=sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2 \ + --hash=sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222 \ + --hash=sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106 \ + --hash=sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272 \ + --hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \ + --hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7 # via -r requirements.in -tomli==2.0.1 \ - --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ - --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f +typing-extensions==4.13.2 \ + --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \ + --hash=sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef # via -r requirements.in -urllib3==2.2.1 \ - --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \ - --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19 +urllib3==2.4.0 \ + --hash=sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466 \ + --hash=sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813 # via # docker # requests -zstandard==0.22.0 \ - --hash=sha256:11f0d1aab9516a497137b41e3d3ed4bbf7b2ee2abc79e5c8b010ad286d7464bd \ - --hash=sha256:1958100b8a1cc3f27fa21071a55cb2ed32e9e5df4c3c6e661c193437f171cba2 \ - --hash=sha256:1a90ba9a4c9c884bb876a14be2b1d216609385efb180393df40e5172e7ecf356 \ - --hash=sha256:1d43501f5f31e22baf822720d82b5547f8a08f5386a883b32584a185675c8fbf \ - --hash=sha256:23d2b3c2b8e7e5a6cb7922f7c27d73a9a615f0a5ab5d0e03dd533c477de23004 \ - --hash=sha256:2612e9bb4977381184bb2463150336d0f7e014d6bb5d4a370f9a372d21916f69 \ - --hash=sha256:275df437ab03f8c033b8a2c181e51716c32d831082d93ce48002a5227ec93019 \ - --hash=sha256:2ac9957bc6d2403c4772c890916bf181b2653640da98f32e04b96e4d6fb3252a \ - --hash=sha256:2b11ea433db22e720758cba584c9d661077121fcf60ab43351950ded20283440 \ - --hash=sha256:2fdd53b806786bd6112d97c1f1e7841e5e4daa06810ab4b284026a1a0e484c0b \ - --hash=sha256:33591d59f4956c9812f8063eff2e2c0065bc02050837f152574069f5f9f17775 \ - --hash=sha256:36a47636c3de227cd765e25a21dc5dace00539b82ddd99ee36abae38178eff9e \ - --hash=sha256:39b2853efc9403927f9065cc48c9980649462acbdf81cd4f0cb773af2fd734bc \ - --hash=sha256:3db41c5e49ef73641d5111554e1d1d3af106410a6c1fb52cf68912ba7a343a0d \ - --hash=sha256:445b47bc32de69d990ad0f34da0e20f535914623d1e506e74d6bc5c9dc40bb09 \ - --hash=sha256:466e6ad8caefb589ed281c076deb6f0cd330e8bc13c5035854ffb9c2014b118c \ - --hash=sha256:48f260e4c7294ef275744210a4010f116048e0c95857befb7462e033f09442fe \ - --hash=sha256:4ac59d5d6910b220141c1737b79d4a5aa9e57466e7469a012ed42ce2d3995e88 \ - --hash=sha256:53866a9d8ab363271c9e80c7c2e9441814961d47f88c9bc3b248142c32141d94 \ - --hash=sha256:589402548251056878d2e7c8859286eb91bd841af117dbe4ab000e6450987e08 \ - --hash=sha256:68953dc84b244b053c0d5f137a21ae8287ecf51b20872eccf8eaac0302d3e3b0 \ - --hash=sha256:6c25b8eb733d4e741246151d895dd0308137532737f337411160ff69ca24f93a \ - --hash=sha256:7034d381789f45576ec3f1fa0e15d741828146439228dc3f7c59856c5bcd3292 \ - --hash=sha256:73a1d6bd01961e9fd447162e137ed949c01bdb830dfca487c4a14e9742dccc93 \ - --hash=sha256:8226a33c542bcb54cd6bd0a366067b610b41713b64c9abec1bc4533d69f51e70 \ - --hash=sha256:888196c9c8893a1e8ff5e89b8f894e7f4f0e64a5af4d8f3c410f0319128bb2f8 \ - --hash=sha256:88c5b4b47a8a138338a07fc94e2ba3b1535f69247670abfe422de4e0b344aae2 \ - --hash=sha256:8a1b2effa96a5f019e72874969394edd393e2fbd6414a8208fea363a22803b45 \ - --hash=sha256:93e1856c8313bc688d5df069e106a4bc962eef3d13372020cc6e3ebf5e045202 \ - --hash=sha256:9501f36fac6b875c124243a379267d879262480bf85b1dbda61f5ad4d01b75a3 \ - --hash=sha256:959665072bd60f45c5b6b5d711f15bdefc9849dd5da9fb6c873e35f5d34d8cfb \ - --hash=sha256:a1d67d0d53d2a138f9e29d8acdabe11310c185e36f0a848efa104d4e40b808e4 \ - --hash=sha256:a493d470183ee620a3df1e6e55b3e4de8143c0ba1b16f3ded83208ea8ddfd91d \ - --hash=sha256:a7ccf5825fd71d4542c8ab28d4d482aace885f5ebe4b40faaa290eed8e095a4c \ - --hash=sha256:a88b7df61a292603e7cd662d92565d915796b094ffb3d206579aaebac6b85d5f \ - --hash=sha256:a97079b955b00b732c6f280d5023e0eefe359045e8b83b08cf0333af9ec78f26 \ - --hash=sha256:d22fdef58976457c65e2796e6730a3ea4a254f3ba83777ecfc8592ff8d77d303 \ - --hash=sha256:d75f693bb4e92c335e0645e8845e553cd09dc91616412d1d4650da835b5449df \ - --hash=sha256:d8593f8464fb64d58e8cb0b905b272d40184eac9a18d83cf8c10749c3eafcd7e \ - --hash=sha256:d8fff0f0c1d8bc5d866762ae95bd99d53282337af1be9dc0d88506b340e74b73 \ - --hash=sha256:de20a212ef3d00d609d0b22eb7cc798d5a69035e81839f549b538eff4105d01c \ - --hash=sha256:e9e9d4e2e336c529d4c435baad846a181e39a982f823f7e4495ec0b0ec8538d2 \ - --hash=sha256:f058a77ef0ece4e210bb0450e68408d4223f728b109764676e1a13537d056bb0 \ - --hash=sha256:f1a4b358947a65b94e2501ce3e078bbc929b039ede4679ddb0460829b12f7375 \ - --hash=sha256:f9b2cde1cd1b2a10246dbc143ba49d942d14fb3d2b4bccf4618d475c65464912 \ - --hash=sha256:fe3390c538f12437b859d815040763abc728955a52ca6ff9c5d4ac707c4ad98e +zstandard==0.23.0 \ + --hash=sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473 \ + --hash=sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916 \ + --hash=sha256:11e3bf3c924853a2d5835b24f03eeba7fc9b07d8ca499e247e06ff5676461a15 \ + --hash=sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072 \ + --hash=sha256:1516c8c37d3a053b01c1c15b182f3b5f5eef19ced9b930b684a73bad121addf4 \ + --hash=sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e \ + --hash=sha256:1bfe8de1da6d104f15a60d4a8a768288f66aa953bbe00d027398b93fb9680b26 \ + --hash=sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8 \ + --hash=sha256:1fd7e0f1cfb70eb2f95a19b472ee7ad6d9a0a992ec0ae53286870c104ca939e5 \ + --hash=sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd \ + --hash=sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c \ + --hash=sha256:29a2bc7c1b09b0af938b7a8343174b987ae021705acabcbae560166567f5a8db \ + --hash=sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5 \ + --hash=sha256:2ef3775758346d9ac6214123887d25c7061c92afe1f2b354f9388e9e4d48acfc \ + --hash=sha256:2f146f50723defec2975fb7e388ae3a024eb7151542d1599527ec2aa9cacb152 \ + --hash=sha256:2fb4535137de7e244c230e24f9d1ec194f61721c86ebea04e1581d9d06ea1269 \ + --hash=sha256:32ba3b5ccde2d581b1e6aa952c836a6291e8435d788f656fe5976445865ae045 \ + --hash=sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e \ + --hash=sha256:379b378ae694ba78cef921581ebd420c938936a153ded602c4fea612b7eaa90d \ + --hash=sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a \ + --hash=sha256:3aa014d55c3af933c1315eb4bb06dd0459661cc0b15cd61077afa6489bec63bb \ + --hash=sha256:4051e406288b8cdbb993798b9a45c59a4896b6ecee2f875424ec10276a895740 \ + --hash=sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105 \ + --hash=sha256:43da0f0092281bf501f9c5f6f3b4c975a8a0ea82de49ba3f7100e64d422a1274 \ + --hash=sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2 \ + --hash=sha256:48ef6a43b1846f6025dde6ed9fee0c24e1149c1c25f7fb0a0585572b2f3adc58 \ + --hash=sha256:50a80baba0285386f97ea36239855f6020ce452456605f262b2d33ac35c7770b \ + --hash=sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4 \ + --hash=sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db \ + --hash=sha256:53ea7cdc96c6eb56e76bb06894bcfb5dfa93b7adcf59d61c6b92674e24e2dd5e \ + --hash=sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9 \ + --hash=sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0 \ + --hash=sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813 \ + --hash=sha256:61062387ad820c654b6a6b5f0b94484fa19515e0c5116faf29f41a6bc91ded6e \ + --hash=sha256:61f89436cbfede4bc4e91b4397eaa3e2108ebe96d05e93d6ccc95ab5714be512 \ + --hash=sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0 \ + --hash=sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b \ + --hash=sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48 \ + --hash=sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a \ + --hash=sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772 \ + --hash=sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed \ + --hash=sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373 \ + --hash=sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea \ + --hash=sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd \ + --hash=sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f \ + --hash=sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc \ + --hash=sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23 \ + --hash=sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2 \ + --hash=sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db \ + --hash=sha256:82d17e94d735c99621bf8ebf9995f870a6b3e6d14543b99e201ae046dfe7de70 \ + --hash=sha256:837bb6764be6919963ef41235fd56a6486b132ea64afe5fafb4cb279ac44f259 \ + --hash=sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9 \ + --hash=sha256:8c24f21fa2af4bb9f2c492a86fe0c34e6d2c63812a839590edaf177b7398f700 \ + --hash=sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003 \ + --hash=sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba \ + --hash=sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a \ + --hash=sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c \ + --hash=sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90 \ + --hash=sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690 \ + --hash=sha256:a05e6d6218461eb1b4771d973728f0133b2a4613a6779995df557f70794fd60f \ + --hash=sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840 \ + --hash=sha256:a4ae99c57668ca1e78597d8b06d5af837f377f340f4cce993b551b2d7731778d \ + --hash=sha256:a8c86881813a78a6f4508ef9daf9d4995b8ac2d147dcb1a450448941398091c9 \ + --hash=sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35 \ + --hash=sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd \ + --hash=sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a \ + --hash=sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea \ + --hash=sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1 \ + --hash=sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573 \ + --hash=sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09 \ + --hash=sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094 \ + --hash=sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78 \ + --hash=sha256:b8c0bd73aeac689beacd4e7667d48c299f61b959475cdbb91e7d3d88d27c56b9 \ + --hash=sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5 \ + --hash=sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9 \ + --hash=sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391 \ + --hash=sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847 \ + --hash=sha256:c7c517d74bea1a6afd39aa612fa025e6b8011982a0897768a2f7c8ab4ebb78a2 \ + --hash=sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c \ + --hash=sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2 \ + --hash=sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057 \ + --hash=sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20 \ + --hash=sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d \ + --hash=sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4 \ + --hash=sha256:e2d1a054f8f0a191004675755448d12be47fa9bebbcffa3cdf01db19f2d30a54 \ + --hash=sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171 \ + --hash=sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e \ + --hash=sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160 \ + --hash=sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b \ + --hash=sha256:f8346bfa098532bc1fb6c7ef06783e969d87a99dd1d2a5a18a892c1d7a643c58 \ + --hash=sha256:f83fa6cae3fff8e98691248c9320356971b59678a17f20656a9e59cd32cee6d8 \ + --hash=sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33 \ + --hash=sha256:fb2b1ecfef1e67897d336de3a0e3f52478182d6a47eda86cbd42504c5cbd009a \ + --hash=sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880 \ + --hash=sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca \ + --hash=sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b \ + --hash=sha256:fe3b385d996ee0822fd46528d9f0443b880d4d05528fd26a9119a54ec3f91c69 # via -r requirements.in diff --git a/src/github.rs b/src/github.rs index 8a432841..0d3bc971 100644 --- a/src/github.rs +++ b/src/github.rs @@ -209,7 +209,7 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<() for artifact in artifacts { if matches!( artifact.name.as_str(), - "pythonbuild" | "sccache" | "toolchain" + "pythonbuild" | "toolchain" ) || artifact.name.contains("install-only") { continue; diff --git a/src/release.rs b/src/release.rs index 10e562ca..0b67888d 100644 --- a/src/release.rs +++ b/src/release.rs @@ -129,6 +129,18 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: }], }, ); + h.insert( + "aarch64-pc-windows-msvc", + TripleRelease { + suffixes: vec!["pgo"], + install_only_suffix: "pgo", + python_version_requirement: Some(VersionSpecifier::from_str(">=3.11").unwrap()), + conditional_suffixes: vec![ConditionalSuffixes { + python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(), + suffixes: vec!["freethreaded+pgo"], + }], + }, + ); // Linux. let linux_suffixes_pgo = vec!["debug", "pgo+lto"]; @@ -141,6 +153,11 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: "lto+static", "noopt+static", ]; + let linux_suffixes_musl_freethreaded = vec![ + "freethreaded+debug", + "freethreaded+lto", + "freethreaded+noopt", + ]; let linux_suffixes_pgo_freethreaded = vec!["freethreaded+debug", "freethreaded+pgo+lto"]; let linux_suffixes_nopgo_freethreaded = vec![ "freethreaded+debug", @@ -151,12 +168,12 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: h.insert( "aarch64-unknown-linux-gnu", TripleRelease { - suffixes: linux_suffixes_nopgo.clone(), - install_only_suffix: "lto", + suffixes: linux_suffixes_pgo.clone(), + install_only_suffix: "pgo+lto", python_version_requirement: None, conditional_suffixes: vec![ConditionalSuffixes { python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(), - suffixes: linux_suffixes_nopgo_freethreaded.clone(), + suffixes: linux_suffixes_pgo_freethreaded.clone(), }], }, ); @@ -274,14 +291,16 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: }], }, ); - // TODO: Python 3.14 support on musl h.insert( "x86_64-unknown-linux-musl", TripleRelease { suffixes: linux_suffixes_musl.clone(), install_only_suffix: "lto", - python_version_requirement: Some(VersionSpecifier::from_str("<3.14").unwrap()), - conditional_suffixes: vec![], + python_version_requirement: None, + conditional_suffixes: vec![ConditionalSuffixes { + python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(), + suffixes: linux_suffixes_musl_freethreaded.clone(), + }], }, ); h.insert( @@ -289,8 +308,11 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: TripleRelease { suffixes: linux_suffixes_musl.clone(), install_only_suffix: "lto", - python_version_requirement: Some(VersionSpecifier::from_str("<3.14").unwrap()), - conditional_suffixes: vec![], + python_version_requirement: None, + conditional_suffixes: vec![ConditionalSuffixes { + python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(), + suffixes: linux_suffixes_musl_freethreaded.clone(), + }], }, ); h.insert( @@ -298,8 +320,11 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: TripleRelease { suffixes: linux_suffixes_musl.clone(), install_only_suffix: "lto", - python_version_requirement: Some(VersionSpecifier::from_str("<3.14").unwrap()), - conditional_suffixes: vec![], + python_version_requirement: None, + conditional_suffixes: vec![ConditionalSuffixes { + python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(), + suffixes: linux_suffixes_musl_freethreaded.clone(), + }], }, ); h.insert( @@ -307,8 +332,11 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy:: TripleRelease { suffixes: linux_suffixes_musl.clone(), install_only_suffix: "lto", - python_version_requirement: Some(VersionSpecifier::from_str("<3.14").unwrap()), - conditional_suffixes: vec![], + python_version_requirement: None, + conditional_suffixes: vec![ConditionalSuffixes { + python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(), + suffixes: linux_suffixes_musl_freethreaded.clone(), + }], }, ); @@ -570,14 +598,14 @@ pub fn produce_install_only_stripped(tar_gz_path: &Path, llvm_dir: &Path) -> Res static LLVM_URL: Lazy = Lazy::new(|| { if cfg!(target_os = "macos") { if std::env::consts::ARCH == "aarch64" { - Url::parse("https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250308/llvm-20.1.0+20250308-aarch64-apple-darwin.tar.zst").unwrap() + Url::parse("https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-aarch64-apple-darwin.tar.zst").unwrap() } else if std::env::consts::ARCH == "x86_64" { - Url::parse("https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250308/llvm-20.1.0+20250308-x86_64-apple-darwin.tar.zst").unwrap() + Url::parse("https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-x86_64-apple-darwin.tar.zst").unwrap() } else { panic!("unsupported macOS architecture"); } } else if cfg!(target_os = "linux") { - Url::parse("https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250308/llvm-20.1.0+20250308-gnu_only-x86_64-unknown-linux-gnu.tar.zst").unwrap() + Url::parse("https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-gnu_only-x86_64-unknown-linux-gnu.tar.zst").unwrap() } else { panic!("unsupported platform"); } diff --git a/src/validation.rs b/src/validation.rs index 747cdaed..9084754b 100644 --- a/src/validation.rs +++ b/src/validation.rs @@ -18,7 +18,7 @@ use { macho::{LoadCommandVariant, MachHeader, Nlist}, pe::{ImageNtHeaders, PeFile, PeFile32, PeFile64}, }, - Endianness, FileKind, Object, SectionIndex, SymbolScope, + Architecture, Endianness, FileKind, Object, SectionIndex, SymbolScope, }, once_cell::sync::Lazy, std::{ @@ -33,6 +33,7 @@ use { const RECOGNIZED_TRIPLES: &[&str] = &[ "aarch64-apple-darwin", "aarch64-apple-ios", + "aarch64-pc-windows-msvc", "aarch64-unknown-linux-gnu", "armv7-unknown-linux-gnueabi", "armv7-unknown-linux-gnueabihf", @@ -117,11 +118,13 @@ const PE_ALLOWED_LIBRARIES: &[&str] = &[ "libcrypto-1_1.dll", "libcrypto-1_1-x64.dll", "libcrypto-3.dll", + "libcrypto-3-arm64.dll", "libcrypto-3-x64.dll", "libffi-8.dll", "libssl-1_1.dll", "libssl-1_1-x64.dll", "libssl-3.dll", + "libssl-3-arm64.dll", "libssl-3-x64.dll", "python3.dll", "python39.dll", @@ -137,8 +140,14 @@ const PE_ALLOWED_LIBRARIES: &[&str] = &[ "tk86t.dll", ]; -// CPython 3.14 uses tcl/tk 8.6.14+ which includes a bundled zlib and dynamically links to msvcrt. -const PE_ALLOWED_LIBRARIES_314: &[&str] = &["msvcrt.dll", "zlib1.dll"]; +// CPython 3.14 and ARM64 use a newer version of tcl/tk (8.6.14+) which includes a bundled zlib that +// dynamically links some system libraries +const PE_ALLOWED_LIBRARIES_314: &[&str] = &[ + "zlib1.dll", + "api-ms-win-crt-private-l1-1-0.dll", // zlib loads this library on arm64, 3.14+ + "msvcrt.dll", // zlib loads this library +]; +const PE_ALLOWED_LIBRARIES_ARM64: &[&str] = &["msvcrt.dll", "zlib1.dll"]; static GLIBC_MAX_VERSION_BY_TRIPLE: Lazy>> = Lazy::new(|| { @@ -496,6 +505,7 @@ static PLATFORM_TAG_BY_TRIPLE: Lazy> = Lazy: [ ("aarch64-apple-darwin", "macosx-11.0-arm64"), ("aarch64-apple-ios", "iOS-aarch64"), + ("aarch64-pc-windows-msvc", "win-arm64"), ("aarch64-unknown-linux-gnu", "linux-aarch64"), ("armv7-unknown-linux-gnueabi", "linux-arm"), ("armv7-unknown-linux-gnueabihf", "linux-arm"), @@ -748,6 +758,7 @@ const GLOBAL_EXTENSIONS_PYTHON_3_13: &[&str] = &[ "_interpqueues", "_interpreters", "_sha2", + "_suggestions", "_sysconfig", "_tokenize", "_typing", @@ -758,11 +769,15 @@ const GLOBAL_EXTENSIONS_PYTHON_3_14: &[&str] = &[ "_interpchannels", "_interpqueues", "_interpreters", + "_remote_debugging", "_sha2", + "_suggestions", "_sysconfig", "_tokenize", "_typing", "_zoneinfo", + "_hmac", + "_types", ]; const GLOBAL_EXTENSIONS_MACOS: &[&str] = &["_scproxy"]; @@ -798,7 +813,8 @@ const GLOBAL_EXTENSIONS_WINDOWS: &[&str] = &[ "winsound", ]; -const GLOBAL_EXTENSIONS_WINDOWS_3_14: &[&str] = &["_wmi"]; +// TODO(zanieb): Move `_zstd` to non-Windows specific once we add support on Unix. +const GLOBAL_EXTENSIONS_WINDOWS_3_14: &[&str] = &["_wmi", "_zstd"]; const GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13: &[&str] = &["_msi"]; @@ -1369,15 +1385,17 @@ fn validate_pe<'data, Pe: ImageNtHeaders>( let lib = String::from_utf8(lib.to_vec())?; match python_major_minor { - "3.9" | "3.10" | "3.11" | "3.12" | "3.13" => {} + "3.11" | "3.12" | "3.13" if pe.architecture() == Architecture::Aarch64 => { + if PE_ALLOWED_LIBRARIES_ARM64.contains(&lib.as_str()) { + continue; + } + } "3.14" => { if PE_ALLOWED_LIBRARIES_314.contains(&lib.as_str()) { continue; } } - _ => { - panic!("unhandled Python version: {}", python_major_minor); - } + _ => {} } if !PE_ALLOWED_LIBRARIES.contains(&lib.as_str()) { @@ -1596,12 +1614,8 @@ fn validate_extension_modules( ]); } - if is_windows && matches!(python_major_minor, "3.13") { - wanted.extend(["_suggestions"]); - } - - if (is_linux || is_macos) && matches!(python_major_minor, "3.13" | "3.14") { - wanted.extend(["_suggestions", "_testexternalinspection"]); + if (is_linux || is_macos) && matches!(python_major_minor, "3.13") { + wanted.insert("_testexternalinspection"); } if (is_linux || is_macos) && matches!(python_major_minor, "3.12" | "3.13" | "3.14") {