Skip to content

feat: add built-in frozendict support for Python 3.15+ #2824

feat: add built-in frozendict support for Python 3.15+

feat: add built-in frozendict support for Python 3.15+ #2824

Workflow file for this run

name: Build
on:
push:
branches:
- main # allow to trigger the workflow with tag push event
pull_request:
types:
- labeled
- unlabeled
- opened
- synchronize
- reopened
- ready_for_review
paths:
- setup.py
- setup.cfg
- pyproject.toml
- MANIFEST.in
- CMakeLists.txt
- include/**
- src/**
- optree/version.py
- .github/workflows/build.yml
release:
types:
- published
# Allow to trigger the workflow manually
workflow_dispatch:
inputs:
task:
description: "Task type"
type: choice
options:
- build-only
- build-and-publish
required: true
nightly-pybind11:
description: "Use nightly pybind11"
type: boolean
required: false
default: false
permissions:
contents: read
concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
OPTREE_CXX_WERROR: "OFF"
_GLIBCXX_USE_CXX11_ABI: "1"
PYTHONUNBUFFERED: "1"
PYTHON_TAG: "py3" # to be updated
PYTHON_VERSION: "3" # to be updated
COLUMNS: "100"
FORCE_COLOR: "1"
CLICOLOR_FORCE: "1"
ALLOW_PRERELEASES: "false"
jobs:
build-sdist:
name: Build sdist
if: |
github.repository_owner == 'metaopt' &&
(github.event_name != 'push' || startsWith(github.ref, 'refs/tags/')) &&
(github.event_name != 'pull_request' || !github.event.pull_request.draft)
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.9 - 3.15"
update-environment: true
- name: Upgrade pip
run: python -m pip install --upgrade pip setuptools
- name: Set __release__
if: |
startsWith(github.ref, 'refs/tags/') ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.task == 'build-and-publish')
run: python .github/workflows/set_release.py
- name: Print version
run: python setup.py --version
- name: Use nightly pybind11
shell: bash
if: |
(github.event_name == 'workflow_dispatch' && github.event.inputs.nightly-pybind11 == 'true') ||
(
github.event_name == 'pull_request' &&
contains(github.event.pull_request.labels.*.name, 'test-with-nightly-pybind11')
)
run: |
python -m pip install --force-reinstall "$(python .github/workflows/set_setup_requires.py)"
echo "::group::pyproject.toml"
cat pyproject.toml
echo "::endgroup::"
- name: Install dependencies
run: python -m pip install --upgrade pip setuptools wheel build
- name: Build sdist
run: python -m build --sdist
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: sdist
path: dist/*.tar.gz
if-no-files-found: error
build-wheels:
name: >-
Build wheels for
${{ startsWith(matrix.python-version, 'pypy') && 'PyPy' || 'CPython' }} ${{ matrix.python-version }}
on ${{ matrix.target.runner }} (${{ matrix.target.platform }} / ${{ matrix.target.archs }})
if: |
github.repository_owner == 'metaopt' &&
(github.event_name != 'push' || startsWith(github.ref, 'refs/tags/')) &&
(github.event_name != 'pull_request' || !github.event.pull_request.draft)
# https://docs.github.com/en/actions/reference/runners/github-hosted-runners
runs-on: ${{ matrix.target.runner }}
strategy:
matrix:
# Reference: https://cibuildwheel.pypa.io
target:
- { runner: ubuntu-latest, platform: linux, archs: "auto64" }
- { runner: ubuntu-latest, platform: linux, archs: "auto32" }
- { runner: ubuntu-24.04-arm, platform: linux, archs: "aarch64" }
- { runner: ubuntu-latest, platform: linux, archs: "ppc64le" }
- { runner: ubuntu-latest, platform: linux, archs: "s390x" }
- { runner: ubuntu-latest, platform: linux, archs: "riscv64" }
- { runner: macos-latest, platform: macos, archs: "auto64" }
- { runner: macos-latest, platform: macos, archs: "x86_64" }
- { runner: windows-latest, platform: windows, archs: "auto64" }
- { runner: windows-latest, platform: windows, archs: "auto32" }
- { runner: windows-11-arm, platform: windows, archs: "ARM64" }
python-version:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.13t"
- "3.14"
- "3.14t"
# - "3.15"
# - "3.15t"
- "pypy-3.11"
exclude:
# Exclude unsupported Python versions
- python-version: "3.9"
target: { archs: "ARM64" }
- python-version: "3.10"
target: { archs: "ARM64" }
- python-version: "pypy-3.11"
target: { archs: "auto32" }
- python-version: "pypy-3.11"
target: { archs: "ppc64le" }
- python-version: "pypy-3.11"
target: { archs: "s390x" }
- python-version: "pypy-3.11"
target: { archs: "riscv64" }
- python-version: "pypy-3.11"
target: { archs: "ARM64" }
include:
# iOS
- python-version: "3.13"
target:
runner: macos-latest
platform: ios
archs: "arm64_iphoneos"
- python-version: "3.14"
target:
runner: macos-latest
platform: ios
archs: "arm64_iphoneos"
# - python-version: "3.15"
# target:
# runner: macos-latest
# platform: ios
# archs: "arm64_iphoneos"
# iOS Simulator
- python-version: "3.13"
target:
runner: macos-latest
platform: ios
archs: "arm64_iphonesimulator"
- python-version: "3.14"
target:
runner: macos-latest
platform: ios
archs: "arm64_iphonesimulator"
# - python-version: "3.15"
# target:
# runner: macos-latest
# platform: ios
# archs: "arm64_iphonesimulator"
# Android
- python-version: "3.13"
target:
runner: ubuntu-latest
platform: android
archs: "arm64_v8a"
- python-version: "3.14"
target:
runner: ubuntu-latest
platform: android
archs: "arm64_v8a"
# - python-version: "3.15"
# target:
# runner: ubuntu-latest
# platform: android
# archs: "arm64_v8a"
# Pyodide
- python-version: "3.12"
target:
runner: ubuntu-latest
platform: pyodide
archs: "wasm32"
- python-version: "3.13"
target:
runner: ubuntu-latest
platform: pyodide
archs: "wasm32"
fail-fast: false
timeout-minutes: 180
steps:
- name: Sanity check for variables
shell: bash
run: |
if [[ '${{ env.ALLOW_PRERELEASES }}' != 'true' &&
'${{ env.ALLOW_PRERELEASES }}' != 'false' ]]; then
echo '::error::Expect ALLOW_PRERELEASES ("${{ env.ALLOW_PRERELEASES }}") to be "true" or "false"' >&2
exit 1
fi
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Determine Python version
shell: bash
run: |
PYTHON_VERSION="${{ matrix.python-version }}"
PYTHON_VERSION="${PYTHON_VERSION%t}"
echo "Using Python version: ${PYTHON_VERSION}"
echo "PYTHON_VERSION=${PYTHON_VERSION}" | tee -a "${GITHUB_ENV}"
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
update-environment: true
allow-prereleases: true
- name: Set up Environment
shell: bash
run: |
python -m pip install --upgrade pip setuptools
if [[ "${{ runner.os }}" == 'macOS' ]]; then
brew update --quiet --force
brew list --formula cmake >/dev/null && brew uninstall --formula cmake || true
brew install --formula cmake
fi
- name: Set __release__
if: |
startsWith(github.ref, 'refs/tags/') ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.task == 'build-and-publish')
run: python .github/workflows/set_release.py
- name: Print version
run: python setup.py --version
- name: Use nightly pybind11
shell: bash
if: |
(github.event_name == 'workflow_dispatch' && github.event.inputs.nightly-pybind11 == 'true') ||
(
github.event_name == 'pull_request' &&
contains(github.event.pull_request.labels.*.name, 'test-with-nightly-pybind11')
)
run: |
python -m pip install --force-reinstall "$(python .github/workflows/set_setup_requires.py)"
echo "::group::pyproject.toml"
cat pyproject.toml
echo "::endgroup::"
- name: Set CIBW_BUILD
shell: bash
run: |
set -x
PYTHON_TAG="$(
echo 'import sys; print(
"{0.name[0]}p{1.major}{1.minor}".format(
sys.implementation,
sys.version_info,
).lower(),
)' | python -
)"
if [[ "${{ matrix.python-version }}" == *"t" ]]; then
PYTHON_TAG="${PYTHON_TAG}t"
fi
echo "PYTHON_TAG=${PYTHON_TAG}" | tee -a "${GITHUB_ENV}"
echo "CIBW_BUILD=${PYTHON_TAG}-*" | tee -a "${GITHUB_ENV}"
if [[ "${{ matrix.target.platform }}" == 'ios' &&
"${{ matrix.target.archs }}" == *simulator* ]]; then
xcrun simctl shutdown all || true
xcrun simctl delete unavailable || true
xcrun simctl list devices >/dev/null || true
xcodebuild -downloadPlatform iOS || true
xcrun simctl list devices available || true
fi
- name: Set up QEMU
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v4
with:
platforms: all
- name: Build wheels
uses: pypa/cibuildwheel@v3.4
env:
CIBW_BUILD: ${{ env.CIBW_BUILD }}
CIBW_PLATFORM: ${{ matrix.target.platform }}
CIBW_ARCHS: ${{ matrix.target.archs }}
CIBW_ENABLE: pypy cpython-freethreading${{ env.ALLOW_PRERELEASES == 'true' && ' cpython-prerelease' || '' }}
CIBW_ALLOW_EMPTY: ${{ env.ALLOW_PRERELEASES == 'true' }}
with:
package-dir: .
output-dir: wheelhouse
config-file: "{package}/pyproject.toml"
- name: Upload wheels
uses: actions/upload-artifact@v7
with:
name: wheels-${{ env.PYTHON_TAG }}-${{ matrix.target.platform }}-${{ matrix.target.archs }}
path: wheelhouse/*.whl
if-no-files-found: ${{ env.ALLOW_PRERELEASES == 'true' && 'warn' || 'error' }}
list-artifacts:
name: List artifacts
runs-on: ubuntu-latest
needs: [build-sdist, build-wheels]
timeout-minutes: 15
steps:
- name: Download built sdist
uses: actions/download-artifact@v8
with:
# unpacks default artifact into dist/
# if `name: artifact` is omitted, the action will create extra parent dir
name: sdist
path: dist
- name: Download built wheels
uses: actions/download-artifact@v8
with:
pattern: wheels-*
path: dist
merge-multiple: true
- name: List distributions
run: ls -lh dist/*
- name: Remove PyPI unsupported files
run: rm -f dist/*wasm*.whl
- name: Upload artifacts
uses: actions/upload-artifact@v7
with:
name: artifacts
path: dist/*
if-no-files-found: error
publish:
name: Publish to PyPI
runs-on: ubuntu-latest
needs: [list-artifacts]
if: |
github.repository_owner == 'metaopt' &&
github.event_name != 'pull_request' &&
(github.event_name != 'workflow_dispatch' || github.event.inputs.task == 'build-and-publish') &&
(github.event_name != 'push' || startsWith(github.ref, 'refs/tags/'))
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
if: startsWith(github.ref, 'refs/tags/')
uses: actions/setup-python@v6
with:
python-version: "3.9 - 3.15"
update-environment: true
- name: Upgrade pip
run: python -m pip install --upgrade pip setuptools
- name: Set __release__
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
run: python .github/workflows/set_release.py
- name: Print version
run: python setup.py --version
- name: Check consistency between the package version and release tag
if: startsWith(github.ref, 'refs/tags/')
run: |
PACKAGE_VER="v$(python setup.py --version)"
RELEASE_TAG="${GITHUB_REF#refs/*/}"
if [[ "${PACKAGE_VER}" != "${RELEASE_TAG}" ]]; then
echo "::error::package ver. (${PACKAGE_VER}) != release tag. (${RELEASE_TAG})" >&2
exit 1
fi
- name: Download built artifacts
uses: actions/download-artifact@v8
with:
# unpacks default artifact into dist/
# if `name: artifact` is omitted, the action will create extra parent dir
name: artifacts
path: dist
- name: List distributions
run: ls -lh dist/*
- name: Publish to TestPyPI
if: |
(startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch') &&
env.ALLOW_PRERELEASES == 'false'
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.TESTPYPI_UPLOAD_TOKEN }}
repository-url: https://test.pypi.org/legacy/
verbose: true
print-hash: true
skip-existing: true
- name: Publish to PyPI
if: |
(startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch') &&
env.ALLOW_PRERELEASES == 'false'
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_UPLOAD_TOKEN }}
verbose: true
print-hash: true
skip-existing: true