From 461d0d6c278ed12969da50f6739783d22e3400ca Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Mon, 5 Oct 2026 22:50:55 +0200 Subject: [PATCH] Enable support of Python 3.15 Add Python 3.15 to the CI matrices and package metadata: - pyproject.toml: add the 3.15 classifier and bump requires-python to <3.16 - clang builds: add 3.15 and allow-prereleases in setup-python - build_pip: add 3.15 rows and the conda-forge/label/python_rc channel - conda-package(-cf): add 3.15 rows (numpy 2.5) and the python_rc channel The 3.15 release candidate on conda-forge depends on the _python_rc package, which is only published in conda-forge/label/python_rc. --- .github/workflows/build-with-clang.yml | 4 +- .../workflows/build-with-standard-clang.yml | 4 +- .github/workflows/build_pip.yml | 11 ++++- .github/workflows/conda-package-cf.yml | 46 ++++++++++++++----- .github/workflows/conda-package.yml | 32 ++++++++++--- CHANGELOG.md | 1 + pyproject.toml | 3 +- 7 files changed, 79 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build-with-clang.yml b/.github/workflows/build-with-clang.yml index 87478d9..ae9886e 100644 --- a/.github/workflows/build-with-clang.yml +++ b/.github/workflows/build-with-clang.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - python: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"] + python: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t", "3.15"] numpy_version: ["'numpy>=2'"] env: ONEAPI_ROOT: /opt/intel/oneapi @@ -45,6 +45,8 @@ jobs: uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python }} + # allow the 3.15 release candidate until 3.15 is final + allow-prereleases: true architecture: x64 - name: Checkout repo diff --git a/.github/workflows/build-with-standard-clang.yml b/.github/workflows/build-with-standard-clang.yml index c2eed53..fef022d 100644 --- a/.github/workflows/build-with-standard-clang.yml +++ b/.github/workflows/build-with-standard-clang.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: - python: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"] + python: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t", "3.15"] numpy_version: ["'numpy>=2'"] env: @@ -39,6 +39,8 @@ jobs: uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python }} + # allow the 3.15 release candidate until 3.15 is final + allow-prereleases: true architecture: x64 - name: Checkout repo diff --git a/.github/workflows/build_pip.yml b/.github/workflows/build_pip.yml index 77d2af3..de22194 100644 --- a/.github/workflows/build_pip.yml +++ b/.github/workflows/build_pip.yml @@ -40,6 +40,14 @@ jobs: python_spec: "3.14.* *_cp314t" free_threaded: "true" use_pre: "--pre" + - python: "3.15" + python_tag: "3.15" + python_spec: "3.15.* *_cp315" + use_pre: "" + - python: "3.15" + python_tag: "3.15" + python_spec: "3.15.* *_cp315" + use_pre: "--pre" steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -50,7 +58,8 @@ jobs: - uses: conda-incubator/setup-miniconda@be893c923ea9cf1cf7cd510fbdde27c7e18cbdcb # v4.1.0 with: miniforge-version: latest - channels: conda-forge + # conda-forge/label/python_rc carries the 3.15 release candidate + channels: conda-forge,conda-forge/label/python_rc activate-environment: test python-version: ${{ matrix.python }} diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index 3e5fde9..01a12a7 100644 --- a/.github/workflows/conda-package-cf.yml +++ b/.github/workflows/conda-package-cf.yml @@ -37,6 +37,10 @@ jobs: numpy: "2.3" python_spec: "3.14.* *_cp314t" python_tag: "3.14t" + - python: "3.15" + numpy: "2.5" + python_spec: "3.15.* *_cp315" + python_tag: "3.15" steps: - name: Cancel Previous Runs @@ -73,7 +77,7 @@ jobs: - name: Build conda package run: | - CHANNELS=(-c conda-forge --override-channels) + CHANNELS=(-c conda-forge -c conda-forge/label/python_rc --override-channels) VERSIONS=(--python "${{ matrix.python_spec || matrix.python }}" --numpy "${{ matrix.numpy }}") TEST=(--no-test) @@ -113,6 +117,10 @@ jobs: numpy: "2.3" python_spec: "3.14.* *_cp314t" python_tag: "3.14t" + - python: "3.15" + numpy: "2.5" + python_spec: "3.15.* *_cp315" + python_tag: "3.15" env: conda-bld: C:\Miniconda\conda-bld\win-64\ @@ -132,7 +140,7 @@ jobs: with: miniforge-version: latest activate-environment: build - channels: conda-forge + channels: conda-forge,conda-forge/label/python_rc python-version: ${{ matrix.python }} - name: Cache conda packages @@ -158,7 +166,7 @@ jobs: conda list -n base - name: Build conda package - run: conda build --no-test --python "${{ matrix.python_spec || matrix.python }}" --numpy ${{ matrix.numpy }} -c conda-forge --override-channels conda-recipe-cf + run: conda build --no-test --python "${{ matrix.python_spec || matrix.python }}" --numpy ${{ matrix.numpy }} -c conda-forge -c conda-forge/label/python_rc --override-channels conda-recipe-cf - name: Upload artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -189,9 +197,13 @@ jobs: numpy: "2.3" python_spec: "3.14.* *_cp314t" python_tag: "3.14t" + - python: "3.15" + numpy: "2.5" + python_spec: "3.15.* *_cp315" + python_tag: "3.15" env: - CHANNELS: -c conda-forge --override-channels + CHANNELS: -c conda-forge -c conda-forge/label/python_rc --override-channels steps: - name: Download artifact @@ -220,7 +232,7 @@ jobs: . "$CONDA/etc/profile.d/conda.sh" PACKAGE_VERSION="$(python -c "${VER_SCRIPT1} ${VER_SCRIPT2}")" export PACKAGE_VERSION - conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" "python=${{ matrix.python_spec || matrix.python }}" "numpy=${{ matrix.numpy }}" -c "$GITHUB_WORKSPACE/channel" -c conda-forge --override-channels --only-deps --dry-run > lockfile + conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" "python=${{ matrix.python_spec || matrix.python }}" "numpy=${{ matrix.numpy }}" -c "$GITHUB_WORKSPACE/channel" -c conda-forge -c conda-forge/label/python_rc --override-channels --only-deps --dry-run > lockfile cat lockfile - name: Set pkgs_dirs @@ -244,7 +256,7 @@ jobs: . "$CONDA/etc/profile.d/conda.sh" PACKAGE_VERSION="$(python -c "${VER_SCRIPT1} ${VER_SCRIPT2}")" export PACKAGE_VERSION - conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" pytest "python=${{ matrix.python_spec || matrix.python }}" "numpy=${{ matrix.numpy }}" -c "$GITHUB_WORKSPACE/channel" -c conda-forge --override-channels + conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" pytest "python=${{ matrix.python_spec || matrix.python }}" "numpy=${{ matrix.numpy }}" -c "$GITHUB_WORKSPACE/channel" -c conda-forge -c conda-forge/label/python_rc --override-channels # Test installed packages conda list @@ -279,9 +291,13 @@ jobs: numpy: "2.3" python_spec: "3.14.* *_cp314t" python_tag: "3.14t" + - python: "3.15" + numpy: "2.5" + python_spec: "3.15.* *_cp315" + python_tag: "3.15" env: - CHANNELS: -c conda-forge --override-channels + CHANNELS: -c conda-forge -c conda-forge/label/python_rc --override-channels steps: - name: Download artifact @@ -371,6 +387,10 @@ jobs: numpy: "2.3" python_spec: "3.14.* *_cp314t" python_tag: "3.14t" + - python: "3.15" + numpy: "2.5" + python_spec: "3.15.* *_cp315" + python_tag: "3.15" steps: - name: Cancel Previous Runs @@ -387,7 +407,7 @@ jobs: with: miniforge-version: latest activate-environment: build - channels: conda-forge + channels: conda-forge,conda-forge/label/python_rc python-version: ${{ matrix.python }} - name: Cache conda packages @@ -416,7 +436,7 @@ jobs: - name: Build conda package shell: bash -el {0} run: | - CHANNELS=(-c conda-forge --override-channels) + CHANNELS=(-c conda-forge -c conda-forge/label/python_rc --override-channels) VERSIONS=(--python "${{ matrix.python_spec || matrix.python }}" --numpy "${{ matrix.numpy }}") TEST=(--no-test) @@ -454,6 +474,10 @@ jobs: numpy: "2.3" python_spec: "3.14.* *_cp314t" python_tag: "3.14t" + - python: "3.15" + numpy: "2.5" + python_spec: "3.15.* *_cp315" + python_tag: "3.15" steps: - name: Download artifact @@ -487,7 +511,7 @@ jobs: run: | PACKAGE_VERSION="$(python -c "${VER_SCRIPT1} ${VER_SCRIPT2}")" export PACKAGE_VERSION - conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" "python=${{ matrix.python_spec || matrix.python }}" "numpy=${{ matrix.numpy }}" -c "$GITHUB_WORKSPACE/channel" -c conda-forge --override-channels --only-deps --dry-run > lockfile + conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" "python=${{ matrix.python_spec || matrix.python }}" "numpy=${{ matrix.numpy }}" -c "$GITHUB_WORKSPACE/channel" -c conda-forge -c conda-forge/label/python_rc --override-channels --only-deps --dry-run > lockfile cat lockfile - name: Cache conda packages @@ -507,7 +531,7 @@ jobs: run: | PACKAGE_VERSION="$(python -c "${VER_SCRIPT1} ${VER_SCRIPT2}")" export PACKAGE_VERSION - conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" pytest "python=${{ matrix.python_spec || matrix.python }}" "numpy=${{ matrix.numpy }}" -c "$GITHUB_WORKSPACE/channel" -c conda-forge --override-channels + conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" pytest "python=${{ matrix.python_spec || matrix.python }}" "numpy=${{ matrix.numpy }}" -c "$GITHUB_WORKSPACE/channel" -c conda-forge -c conda-forge/label/python_rc --override-channels # Test installed packages conda list -n "${{ env.TEST_ENV_NAME }}" diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml index b00aa91..225d121 100644 --- a/.github/workflows/conda-package.yml +++ b/.github/workflows/conda-package.yml @@ -39,6 +39,10 @@ jobs: numpy: "2.3" python_spec: "3.14.* *_cp314t" python_tag: "3.14t" + - python: "3.15" + numpy: "2.5" + python_spec: "3.15.* *_cp315" + python_tag: "3.15" steps: - name: Cancel Previous Runs @@ -92,7 +96,7 @@ jobs: - name: Build conda package run: | - CHANNELS=(-c https://software.repos.intel.com/python/conda -c conda-forge --override-channels) + CHANNELS=(-c https://software.repos.intel.com/python/conda -c conda-forge -c conda-forge/label/python_rc --override-channels) VERSIONS=(--python "${{ matrix.python_spec || matrix.python }}" --numpy "${{ matrix.numpy }}") TEST=(--no-test) @@ -132,6 +136,10 @@ jobs: numpy: "2.3" python_spec: "3.14.* *_cp314t" python_tag: "3.14t" + - python: "3.15" + numpy: "2.5" + python_spec: "3.15.* *_cp315" + python_tag: "3.15" steps: - name: Cancel Previous Runs @@ -149,7 +157,7 @@ jobs: auto-update-conda: true miniforge-version: latest activate-environment: build - channels: conda-forge + channels: conda-forge,conda-forge/label/python_rc python-version: ${{ matrix.python }} conda-build-version: ${{ env.CONDA_BUILD_VERSION }} @@ -179,7 +187,7 @@ jobs: conda list -n base - name: Build conda package - run: conda build --no-test --python "${{ matrix.python_spec || matrix.python }}" --numpy "${{ matrix.numpy }}" -c https://software.repos.intel.com/python/conda -c conda-forge --override-channels conda-recipe + run: conda build --no-test --python "${{ matrix.python_spec || matrix.python }}" --numpy "${{ matrix.numpy }}" -c https://software.repos.intel.com/python/conda -c conda-forge -c conda-forge/label/python_rc --override-channels conda-recipe - name: Upload artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -207,10 +215,15 @@ jobs: python_tag: "3.14t" numpy: 'numpy">=2"' experimental: false + - python: "3.15" + python_spec: "3.15.* *_cp315" + python_tag: "3.15" + numpy: 'numpy">=2"' + experimental: false continue-on-error: ${{ matrix.experimental }} env: - CHANNELS: -c https://software.repos.intel.com/python/conda -c conda-forge --override-channels + CHANNELS: -c https://software.repos.intel.com/python/conda -c conda-forge -c conda-forge/label/python_rc --override-channels steps: - name: Download artifact @@ -252,7 +265,7 @@ jobs: . "$CONDA/etc/profile.d/conda.sh" PACKAGE_VERSION="$(python -c "${VER_SCRIPT1} ${VER_SCRIPT2}")" export PACKAGE_VERSION - conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" "python=${{ matrix.python_spec || matrix.python }}" ${{ matrix.numpy }} -c "$GITHUB_WORKSPACE/channel" -c https://software.repos.intel.com/python/conda -c conda-forge --override-channels --only-deps --dry-run > lockfile + conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" "python=${{ matrix.python_spec || matrix.python }}" ${{ matrix.numpy }} -c "$GITHUB_WORKSPACE/channel" -c https://software.repos.intel.com/python/conda -c conda-forge -c conda-forge/label/python_rc --override-channels --only-deps --dry-run > lockfile cat lockfile - name: Set pkgs_dirs @@ -276,7 +289,7 @@ jobs: . "$CONDA/etc/profile.d/conda.sh" PACKAGE_VERSION="$(python -c "${VER_SCRIPT1} ${VER_SCRIPT2}")" export PACKAGE_VERSION - conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" pytest "python=${{ matrix.python_spec || matrix.python }}" ${{ matrix.numpy }} -c "$GITHUB_WORKSPACE/channel" -c https://software.repos.intel.com/python/conda -c conda-forge --override-channels + conda create -n "${{ env.TEST_ENV_NAME }}" "${PACKAGE_NAME}=${PACKAGE_VERSION}" pytest "python=${{ matrix.python_spec || matrix.python }}" ${{ matrix.numpy }} -c "$GITHUB_WORKSPACE/channel" -c https://software.repos.intel.com/python/conda -c conda-forge -c conda-forge/label/python_rc --override-channels conda activate "${{ env.TEST_ENV_NAME }}" # Test installed packages @@ -308,10 +321,15 @@ jobs: python_tag: "3.14t" numpy: 'numpy">=2"' experimental: false + - python: "3.15" + python_spec: "3.15.* *_cp315" + python_tag: "3.15" + numpy: 'numpy">=2"' + experimental: false continue-on-error: ${{ matrix.experimental }} env: - CHANNELS: -c https://software.repos.intel.com/python/conda -c conda-forge --override-channels + CHANNELS: -c https://software.repos.intel.com/python/conda -c conda-forge -c conda-forge/label/python_rc --override-channels steps: - name: Download artifact diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf2d23..f45a815 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Added support for free-threaded (GIL-disabled) CPython builds: the Cython extension is compiled with `freethreading_compatible=True`, so importing `mkl_random` no longer re-enables the GIL [gh-159](https://github.com/IntelPython/mkl_random/pull/159) * Added a thread-safety section to the how-to guide for free-threaded Python [gh-159](https://github.com/IntelPython/mkl_random/pull/159) * Added an [ASV](https://asv.readthedocs.io/en/stable/) benchmark suite under `benchmarks/` and a `benchmark` optional dependency group [gh-184](https://github.com/IntelPython/mkl_random/pull/184) +* Enabled support of Python 3.15 [gh-188](https://github.com/IntelPython/mkl_random/pull/188) ### Changed * Sped up `normal`, `uniform`, `exponential`, `laplace`, `gumbel`, `logistic`, `rayleigh` and `lognormal` for array-valued parameters. Seeded results change for these array paths; scalar paths are unchanged [gh-171](https://github.com/IntelPython/mkl_random/pull/171) diff --git a/pyproject.toml b/pyproject.toml index 763dcfe..e8fdbef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.15", "Programming Language :: Python :: Free Threading :: 2 - Beta", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development", @@ -77,7 +78,7 @@ keywords = [ license = "BSD-3-Clause" name = "mkl_random" readme = { file = "README.md", content-type = "text/markdown" } -requires-python = ">=3.10,<3.15" +requires-python = ">=3.10,<3.16" [project.optional-dependencies] benchmark = ["asv>=0.6", "psutil"]