diff --git a/.env b/.env index ca77b9441d7b..56f05eb924b4 100644 --- a/.env +++ b/.env @@ -98,5 +98,6 @@ VCPKG="9b965a116838c6cdcd36bca60d1b81b030c8ab8d" # 2026.05.27 (not release, u # ci/docker/python-*-windows-*.dockerfile or the vcpkg config. # This is a workaround for our CI problem that "archery docker build" doesn't # use pulled built images in dev/tasks/python-wheels/github.windows.yml. -PYTHON_WHEEL_WINDOWS_IMAGE_REVISION=2026-07-24 -PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION=2026-07-24 +PYTHON_WHEEL_WINDOWS_IMAGE_REVISION=2026-08-14 +PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION=2026-08-14 + diff --git a/ci/conda_env_python.txt b/ci/conda_env_python.txt index a0dca4eac172..6cf8ba016c72 100644 --- a/ci/conda_env_python.txt +++ b/ci/conda_env_python.txt @@ -24,7 +24,7 @@ cython>=3.1 cloudpickle fsspec hypothesis -libcst>=1.8.6 +libcst>=1.9.0 numpy>=1.16.6 pytest pytest-faulthandler diff --git a/ci/docker/python-free-threaded-wheel-musllinux-test-imports.dockerfile b/ci/docker/python-free-threaded-wheel-musllinux-test-imports.dockerfile index af56749202d4..69ddaf70d589 100644 --- a/ci/docker/python-free-threaded-wheel-musllinux-test-imports.dockerfile +++ b/ci/docker/python-free-threaded-wheel-musllinux-test-imports.dockerfile @@ -35,7 +35,8 @@ RUN apk update && \ # See available releases at: https://github.com/astral-sh/python-build-standalone/releases RUN set -e; \ case "${python_version}" in \ - 3.14) python_patch_version="3.14.5";; \ + 3.14) python_patch_version="3.14.7";; \ + 3.15) python_patch_version="3.15.0rc1";; \ esac && \ curl -L -o python.tar.zst \ https://github.com/astral-sh/python-build-standalone/releases/download/${build_date}/cpython-${python_patch_version}+${build_date}-${arch}-unknown-linux-musl-freethreaded+lto-full.tar.zst && \ diff --git a/ci/docker/python-free-threaded-wheel-musllinux-test-unittests.dockerfile b/ci/docker/python-free-threaded-wheel-musllinux-test-unittests.dockerfile index f2e08a2bfa72..d27c18ececab 100644 --- a/ci/docker/python-free-threaded-wheel-musllinux-test-unittests.dockerfile +++ b/ci/docker/python-free-threaded-wheel-musllinux-test-unittests.dockerfile @@ -37,7 +37,8 @@ RUN apk update && \ # See available releases at: https://github.com/astral-sh/python-build-standalone/releases RUN set -e; \ case "${python_version}" in \ - 3.14) python_patch_version="3.14.5";; \ + 3.14) python_patch_version="3.14.7";; \ + 3.15) python_patch_version="3.15.0rc1";; \ esac && \ curl -L -o python.tar.zst \ https://github.com/astral-sh/python-build-standalone/releases/download/${build_date}/cpython-${python_patch_version}+${build_date}-${arch}-unknown-linux-musl-freethreaded+lto-full.tar.zst && \ diff --git a/ci/docker/python-free-threaded-wheel-windows-test-vs2022.dockerfile b/ci/docker/python-free-threaded-wheel-windows-test-vs2022.dockerfile index 98295c91d0bb..d6af6f174fd7 100644 --- a/ci/docker/python-free-threaded-wheel-windows-test-vs2022.dockerfile +++ b/ci/docker/python-free-threaded-wheel-windows-test-vs2022.dockerfile @@ -26,13 +26,17 @@ FROM ${base} ARG python=3.14 +# PYTHON_RELEASE is the python.org ftp directory, which for a pre-release is the +# final release it leads to, e.g. 3.15.0/python-3.15.0rc1-amd64.exe # hadolint ignore=SC1072 -RUN (if "%python%"=="3.14" setx PYTHON_VERSION "3.14.5") +RUN (if "%python%"=="3.14" setx PYTHON_VERSION "3.14.7" && setx PYTHON_RELEASE "3.14.7") & \ + (if "%python%"=="3.15" setx PYTHON_VERSION "3.15.0rc1" && setx PYTHON_RELEASE "3.15.0") SHELL ["powershell", "-NoProfile", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] RUN $version = $env:PYTHON_VERSION; \ + $release = $env:PYTHON_RELEASE; \ $filename = 'python-' + $version + '-amd64.exe'; \ - $url = 'https://www.python.org/ftp/python/' + $version + '/' + $filename; \ + $url = 'https://www.python.org/ftp/python/' + $release + '/' + $filename; \ Invoke-WebRequest -Uri $url -OutFile $filename; \ Start-Process -FilePath $filename -ArgumentList '/quiet', 'Include_freethreaded=1' -Wait diff --git a/ci/docker/python-wheel-windows-test-vs2022.dockerfile b/ci/docker/python-wheel-windows-test-vs2022.dockerfile index fcb65ba2314e..e4e8728d3ad4 100644 --- a/ci/docker/python-wheel-windows-test-vs2022.dockerfile +++ b/ci/docker/python-wheel-windows-test-vs2022.dockerfile @@ -31,7 +31,9 @@ ARG python=3.11 RUN (if "%python%"=="3.11" setx PYTHON_VERSION "3.11.9" && setx PYTHON_CMD "py -3.11") & \ (if "%python%"=="3.12" setx PYTHON_VERSION "3.12.10" && setx PYTHON_CMD "py -3.12") & \ (if "%python%"=="3.13" setx PYTHON_VERSION "3.13.14" && setx PYTHON_CMD "py -3.13") & \ - (if "%python%"=="3.14" setx PYTHON_VERSION "3.14.6" && setx PYTHON_CMD "py -3.14") + (if "%python%"=="3.14" setx PYTHON_VERSION "3.14.7" && setx PYTHON_CMD "py -3.14") & \ + (if "%python%"=="3.15" setx PYTHON_VERSION "3.15.0-rc1" && setx PYTHON_CMD "py -3.15") + # hadolint ignore=DL3059 RUN choco install -r -y --pre --no-progress --force python --version=%PYTHON_VERSION% diff --git a/ci/scripts/install_python.sh b/ci/scripts/install_python.sh index f6502b1be8ce..7aeda91f727d 100755 --- a/ci/scripts/install_python.sh +++ b/ci/scripts/install_python.sh @@ -28,8 +28,11 @@ declare -A versions versions=([3.11]=3.11.9 [3.12]=3.12.10 [3.13]=3.13.14 - [3.14]=3.14.6 - [3.14t]=3.14.6) + [3.14]=3.14.7 + [3.14t]=3.14.7 + [3.15]=3.15.0rc1 + [3.15t]=3.15.0rc1 + ) if [ "$#" -ne 2 ]; then echo "Usage: $0 " @@ -46,11 +49,14 @@ full_version=${versions[$2]} if [ "$platform" = "macOS" ]; then echo "Downloading Python installer..." + # Match python.org directory by truncating any pre-release suffix: + # 3.15.0rc1 is https://www.python.org/ftp/python/3.15.0/python-3.15.0rc1-macos11.pkg + release_version="${full_version%%[abrc]*}" fname="python-${full_version}-macos11.pkg" - wget "https://www.python.org/ftp/python/${full_version}/${fname}" + wget "https://www.python.org/ftp/python/${release_version}/${fname}" echo "Installing Python..." - if [[ $2 == "3.14t" ]]; then + if [[ $2 == *t ]]; then # Extract the base version without 't' suffix base_version="${version%t}" # See https://github.com/python/cpython/issues/120098#issuecomment-2151122033 for more info on this. @@ -78,7 +84,7 @@ EOF rm "$fname" python="/Library/Frameworks/Python.framework/Versions/${version}/bin/python${version}" - if [[ $2 == "3.14t" ]]; then + if [[ $2 == *t ]]; then base_version="${version%t}" python="/Library/Frameworks/PythonT.framework/Versions/${base_version}/bin/python${base_version}t" fi diff --git a/ci/scripts/python_wheel_macos_build.sh b/ci/scripts/python_wheel_macos_build.sh index b931dfa4dd23..4724f8e15246 100755 --- a/ci/scripts/python_wheel_macos_build.sh +++ b/ci/scripts/python_wheel_macos_build.sh @@ -48,9 +48,15 @@ else exit 1 fi +wheel_build_binary_flag="--only-binary=:all:" +if python -c "import sys; sys.exit(0 if sys.version_info[:2] == (3, 15) else 1)"; then + # TODO: 3.15 workaround due to pyyaml (via libcst). Remove once pyyaml ships 3.15 wheels. + wheel_build_binary_flag="" +fi + pip install \ --force-reinstall \ - --only-binary=:all: \ + ${wheel_build_binary_flag} \ --upgrade \ -r "${source_dir}/python/requirements-wheel-build.txt" pip install "delocate>=0.10.3" diff --git a/ci/scripts/python_wheel_unix_test.sh b/ci/scripts/python_wheel_unix_test.sh index cb445611e233..14fccc05a786 100755 --- a/ci/scripts/python_wheel_unix_test.sh +++ b/ci/scripts/python_wheel_unix_test.sh @@ -47,7 +47,12 @@ export PYARROW_TEST_GANDIVA=OFF export PYARROW_TEST_GCS=${ARROW_GCS} export PYARROW_TEST_HDFS=ON export PYARROW_TEST_ORC=ON -export PYARROW_TEST_PANDAS=ON +# TODO: To be removed once pandas provides wheels for Python 3.15 +if python -c "import sys; sys.exit(0 if sys.version_info < (3, 15) else 1)"; then + export PYARROW_TEST_PANDAS=ON +else + export PYARROW_TEST_PANDAS=OFF +fi export PYARROW_TEST_PARQUET=ON export PYARROW_TEST_PARQUET_ENCRYPTION=ON export PYARROW_TEST_SUBSTRAIT=${ARROW_SUBSTRAIT} diff --git a/ci/scripts/python_wheel_windows_test.bat b/ci/scripts/python_wheel_windows_test.bat index 1e9cacac8bfa..9d4d06249e4d 100755 --- a/ci/scripts/python_wheel_windows_test.bat +++ b/ci/scripts/python_wheel_windows_test.bat @@ -26,7 +26,9 @@ set PYARROW_TEST_GANDIVA=OFF set PYARROW_TEST_GCS=ON set PYARROW_TEST_HDFS=ON set PYARROW_TEST_ORC=ON -set PYARROW_TEST_PANDAS=ON +@REM TODO: To be removed once pandas provides wheels for Python 3.15 +%PYTHON_CMD% -c "import sys; sys.exit(0 if sys.version_info < (3, 15) else 1)" +if errorlevel 1 (set PYARROW_TEST_PANDAS=OFF) else (set PYARROW_TEST_PANDAS=ON) set PYARROW_TEST_PARQUET=ON set PYARROW_TEST_PARQUET_ENCRYPTION=ON set PYARROW_TEST_SUBSTRAIT=ON diff --git a/compose.yaml b/compose.yaml index 6809d6994b6c..dd42cde6093e 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1178,7 +1178,7 @@ services: args: arch: ${ARCH} arch_short: ${ARCH_SHORT} - base: quay.io/pypa/manylinux_2_28_${ARCH_ALIAS}:2026.05.31-3 + base: quay.io/pypa/manylinux_2_28_${ARCH_ALIAS}:2026.08.08-1 manylinux: 2_28 python: ${PYTHON} python_abi_tag: ${PYTHON_ABI_TAG} @@ -1203,7 +1203,7 @@ services: args: arch: ${ARCH} arch_short: ${ARCH_SHORT} - base: quay.io/pypa/musllinux_1_2_${ARCH_ALIAS}:2026.05.31-3 + base: quay.io/pypa/musllinux_1_2_${ARCH_ALIAS}:2026.08.08-1 musllinux: 1_2 python: ${PYTHON} python_abi_tag: ${PYTHON_ABI_TAG} @@ -1244,7 +1244,7 @@ services: args: base: "alpine:${ALPINE_LINUX}" python_version: ${PYTHON} - build_date: "20260510" # python-build-standalone release date + build_date: "20260807" # python-build-standalone release date arch: ${ARCH_ALIAS} context: . dockerfile: ci/docker/python-free-threaded-wheel-musllinux-test-imports.dockerfile @@ -1288,7 +1288,7 @@ services: args: base: "alpine:${ALPINE_LINUX}" python_version: ${PYTHON} - build_date: "20260510" # python-build-standalone release date + build_date: "20260807" # python-build-standalone release date arch: ${ARCH_ALIAS} context: . dockerfile: ci/docker/python-free-threaded-wheel-musllinux-test-unittests.dockerfile diff --git a/dev/tasks/python-wheels/github.linux.yml b/dev/tasks/python-wheels/github.linux.yml index e9e36566ba8d..b1a2e0de5ccb 100644 --- a/dev/tasks/python-wheels/github.linux.yml +++ b/dev/tasks/python-wheels/github.linux.yml @@ -32,7 +32,7 @@ jobs: {% endif %} env: {% if linux_wheel_kind == "musllinux" %} - ALPINE_LINUX: "3.22" + ALPINE_LINUX: "3.23" {% endif %} # archery uses these environment variables {% if arch == "amd64" %} @@ -42,7 +42,12 @@ jobs: {% endif %} PYTHON: "{{ python_version }}" PYTHON_ABI_TAG: "{{ python_abi_tag }}" + {% if python_version == "3.15" %} + # TODO: Remove -rc suffix after 3.15 release + PYTHON_IMAGE_TAG: "{{ python_version }}-rc" + {% else %} PYTHON_IMAGE_TAG: "{{ python_version }}" + {% endif %} steps: {{ macros.github_checkout_arrow()|indent }} diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml index 1a22c7915590..a2230c2fbafa 100644 --- a/dev/tasks/tasks.yml +++ b/dev/tasks/tasks.yml @@ -142,7 +142,10 @@ tasks: ("3.12", "cp312", "cp312"), ("3.13", "cp313", "cp313"), ("3.14", "cp314", "cp314"), - ("3.14", "cp314", "cp314t")] %} + ("3.14", "cp314", "cp314t"), + ("3.15", "cp315", "cp315"), + ("3.15", "cp315", "cp315t") + ] %} {############################## Wheel Linux ##################################} diff --git a/python/pyproject.toml b/python/pyproject.toml index ab6f2e6061c1..92ba53b2a539 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -20,7 +20,7 @@ requires = [ "scikit-build-core >= 1.0", "cython >= 3.1", # Needed for build-time stub docstring extraction - "libcst>=1.8.6", + "libcst>=1.9.0", "numpy>=1.25", "setuptools_scm[toml]>=8", ] diff --git a/python/requirements-build.txt b/python/requirements-build.txt index 2ed711613b41..b5cf678eec86 100644 --- a/python/requirements-build.txt +++ b/python/requirements-build.txt @@ -1,6 +1,6 @@ build cython>=3.1 -libcst>=1.8.6 +libcst>=1.9.0 numpy>=1.25 scikit-build-core>=1.0 setuptools_scm>=8 diff --git a/python/requirements-test.txt b/python/requirements-test.txt index 988d7a3ae7a9..6af9aba6aeb3 100644 --- a/python/requirements-test.txt +++ b/python/requirements-test.txt @@ -1,7 +1,7 @@ cffi hypothesis packaging -pandas +pandas; python_version < "3.15" # TODO: temporary - reenable when 3.15 wheels ship pytest pytest-xdist pytz diff --git a/python/requirements-wheel-build.txt b/python/requirements-wheel-build.txt index 3d1d1c9b8db8..ede700ae2a86 100644 --- a/python/requirements-wheel-build.txt +++ b/python/requirements-wheel-build.txt @@ -1,7 +1,7 @@ build cython>=3.1 # Needed for build-time stub docstring extraction -libcst>=1.8.6 +libcst>=1.9.0 numpy>=2.0.0 scikit-build-core>=1.0 setuptools_scm diff --git a/python/requirements-wheel-test.txt b/python/requirements-wheel-test.txt index fb259db57984..00c0fcc4684f 100644 --- a/python/requirements-wheel-test.txt +++ b/python/requirements-wheel-test.txt @@ -16,6 +16,7 @@ numpy~=1.23.2; python_version < "3.11" numpy~=1.23.2; python_version == "3.11" numpy~=1.26.0; python_version == "3.12" numpy~=2.1.0; python_version == "3.13" -numpy~=2.3.3; python_version >= "3.14" +numpy~=2.3.3; python_version == "3.14" +numpy~=2.5.2; python_version == "3.15" # TODO: 2.5.2 is for 3.15-rc1, after release, update to correct version -pandas +pandas; python_version < "3.15" # TODO: temporary - reenable when 3.15 wheels ship