From 48aab881630d544ae28fe77fdc66e8c453a052ee Mon Sep 17 00:00:00 2001 From: Yoshihiro Misawa Date: Mon, 5 Oct 2026 21:04:57 +0900 Subject: [PATCH 1/4] ci: pin runner images to explicit OS versions Replace the moving -latest labels with the newest generally available images (Ubuntu 26.04, Windows Server 2025, and macOS 26) so runner upgrades happen deliberately. --- .github/workflows/build.yaml | 6 +++--- .github/workflows/test.yml | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 71d2287..9ddc103 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -18,7 +18,7 @@ jobs: build-sdist: name: Source distribution if: startsWith(github.ref, 'refs/tags/v') - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@v7 with: @@ -48,7 +48,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-26.04, windows-2025, macos-26] steps: - name: Set up QEMU @@ -73,7 +73,7 @@ jobs: name: Publish to PyPI if: startsWith(github.ref, 'refs/tags/v') needs: [build-sdist, build-wheels] - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 environment: name: pypi url: https://pypi.org/project/cchardet/ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 31b175e..4e2126c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ concurrency: jobs: native-safety: name: Native ASan / UBSan - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@v7 with: @@ -40,7 +40,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-26.04, windows-2025, macos-26] python-version: ["3.11", "3.12", "3.13", "3.14", "3.14t", "3.15", "3.15t"] steps: @@ -57,11 +57,11 @@ jobs: run: uv sync --locked - name: Lint - if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.14' + if: matrix.os == 'ubuntu-26.04' && matrix.python-version == '3.14' run: uv run ruff check - name: Type check - if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.14' + if: matrix.os == 'ubuntu-26.04' && matrix.python-version == '3.14' run: uv run mypy - name: Test @@ -69,7 +69,7 @@ jobs: package: name: Verify distributions - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@v7 with: From a2a59f2648df3aa711ae39e56a312c225928b303 Mon Sep 17 00:00:00 2001 From: Yoshihiro Misawa Date: Mon, 5 Oct 2026 21:06:51 +0900 Subject: [PATCH 2/4] feat: build and test on native arm64 runners Add Ubuntu 26.04 arm64 and Windows 11 arm64 runners to the test and wheel matrices. Linux aarch64 wheels are now built natively instead of under QEMU, and Windows ARM64 wheels are published for the first time. macOS already runs on Apple silicon and keeps building both x86_64 and arm64 wheels. Name wheel artifacts after the runner label so the two Linux and two Windows jobs do not collide. --- .github/workflows/build.yaml | 10 ++-------- .github/workflows/test.yml | 2 +- CHANGES.md | 4 ++++ README.md | 6 +++--- pyproject.toml | 3 --- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9ddc103..3959689 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -48,15 +48,9 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-26.04, windows-2025, macos-26] + os: [ubuntu-26.04, ubuntu-26.04-arm, windows-2025, windows-11-arm, macos-26] steps: - - name: Set up QEMU - if: runner.os == 'Linux' - uses: docker/setup-qemu-action@v4 - with: - platforms: arm64 - - uses: actions/checkout@v7 with: submodules: recursive @@ -65,7 +59,7 @@ jobs: - uses: actions/upload-artifact@v7 with: - name: wheels-${{ runner.os }} + name: wheels-${{ matrix.os }} path: wheelhouse/*.whl if-no-files-found: error diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4e2126c..41f77d8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,7 +40,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-26.04, windows-2025, macos-26] + os: [ubuntu-26.04, ubuntu-26.04-arm, windows-2025, windows-11-arm, macos-26] python-version: ["3.11", "3.12", "3.13", "3.14", "3.14t", "3.15", "3.15t"] steps: diff --git a/CHANGES.md b/CHANGES.md index e309090..6061a5f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,10 @@ - Support Python 3.15, including the free-threaded CPython 3.15 build, with tests and wheels for Linux, macOS, and Windows +- Publish Windows ARM64 wheels, and build Linux aarch64 wheels on native arm64 + runners instead of under QEMU emulation +- Test every supported Python version on arm64 Linux and Windows in addition to + x86-64 ## 2.3.0 (2026-09-16) diff --git a/README.md b/README.md index 74a4556..3b26fae 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ cChardet is a high-speed universal character encoding detector built on the ## Python support cChardet supports CPython 3.11 through 3.15, including the free-threaded -CPython 3.14 and 3.15 builds. Each version is tested on Linux, macOS, and -Windows. +CPython 3.14 and 3.15 builds. Each version is tested on Linux and Windows on +both x86-64 and arm64, and on macOS on Apple silicon. ## Development @@ -239,6 +239,6 @@ See **COPYING** file. ## Support Platforms -- Windows x86, x86_64 +- Windows x86, x86_64, ARM64 - Linux x86_64, aarch64 - macOS x86_64, arm64 diff --git a/pyproject.toml b/pyproject.toml index fd139c7..8f1fb40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,8 +73,5 @@ archs = "auto" test-command = "python tools/wheel_smoke.py" test-sources = ["tools/wheel_smoke.py"] -[tool.cibuildwheel.linux] -archs = ["auto", "aarch64"] - [tool.cibuildwheel.macos] archs = ["x86_64", "arm64"] From 6a5ad3cf7bbf14296311af2971af1297010b8163 Mon Sep 17 00:00:00 2001 From: Yoshihiro Misawa Date: Mon, 5 Oct 2026 21:24:37 +0900 Subject: [PATCH 3/4] ci: test Windows ARM64 with a native interpreter uv resolved the matrix versions to emulated x86-64 interpreters on the windows-11-arm runner, so those jobs never exercised ARM64 and the free-threaded 3.15 job failed while building an x86-64 dependency with the ARM64 Rust toolchain. Request the aarch64 build explicitly there, and check on every runner that the interpreter architecture matches the runner. --- .github/workflows/test.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 41f77d8..a6f9b15 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,11 +51,19 @@ jobs: - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: version: latest-known - python-version: ${{ matrix.python-version }} + # On Windows ARM64, uv picks an emulated x86-64 interpreter unless the + # request names the architecture. + python-version: ${{ matrix.os == 'windows-11-arm' && format('cpython-{0}-windows-aarch64-none', matrix.python-version) || matrix.python-version }} - name: Install locked dependencies run: uv sync --locked + - name: Check interpreter architecture + run: >- + uv run --no-sync python -c "import os, sysconfig; + plat = sysconfig.get_platform(); print(plat); + assert ('arm64' in plat or 'aarch64' in plat) == (os.environ['RUNNER_ARCH'] == 'ARM64')" + - name: Lint if: matrix.os == 'ubuntu-26.04' && matrix.python-version == '3.14' run: uv run ruff check From d422c7878fd4095698f4309edb4fadba38c1271d Mon Sep 17 00:00:00 2001 From: Yoshihiro Misawa Date: Mon, 5 Oct 2026 21:27:34 +0900 Subject: [PATCH 4/4] ci: handle universal2 interpreters in the architecture check macOS runners provide python.org universal2 interpreters, whose sysconfig platform names neither architecture alone. Check the running process architecture for those builds instead. --- .github/workflows/test.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a6f9b15..21e262a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -59,10 +59,19 @@ jobs: run: uv sync --locked - name: Check interpreter architecture - run: >- - uv run --no-sync python -c "import os, sysconfig; - plat = sysconfig.get_platform(); print(plat); - assert ('arm64' in plat or 'aarch64' in plat) == (os.environ['RUNNER_ARCH'] == 'ARM64')" + shell: bash + run: | + uv run --no-sync python - <<'EOF' + import os + import platform + import sysconfig + + plat = sysconfig.get_platform() + # A universal2 build covers both macOS architectures, so check the running process. + arch = platform.machine() if plat.endswith("universal2") else plat + print(plat, arch) + assert ("arm64" in arch or "aarch64" in arch) == (os.environ["RUNNER_ARCH"] == "ARM64") + EOF - name: Lint if: matrix.os == 'ubuntu-26.04' && matrix.python-version == '3.14'