From 4ede48c89b8ec80bbd1895357f272c5fb61bc9b6 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Wed, 8 Jan 2025 12:23:31 +0100 Subject: [PATCH] GH-44421: [Python] Add configuration for building & testing free-threaded wheels on Windows (#44804) ### Rationale for this change There's no blockers anymore for building Windows wheels for the free-threaded build, so this PR adds the necessary configuration to do that. ### What changes are included in this PR? - Add jobs to build free-threaded wheels on Windows - Move VCPKG-related stuff to a reusable base job ### Are these changes tested? No tests required. ### Are there any user-facing changes? No. * GitHub Issue: #44421 Lead-authored-by: Antoine Pitrou Co-authored-by: Lysandros Nikolaou Signed-off-by: Sutou Kouhei --- .env | 5 +- .pre-commit-config.yaml | 2 +- ...eaded-wheel-windows-test-vs2019.dockerfile | 52 ++++++++++++ ...e-threaded-wheel-windows-vs2019.dockerfile | 49 +++++++++++ ...-wheel-windows-test-vs2019-base.dockerfile | 51 ++++++++++++ ...ython-wheel-windows-test-vs2019.dockerfile | 56 +++++-------- ...ython-wheel-windows-vs2019-base.dockerfile | 79 ++++++++++++++++++ .../python-wheel-windows-vs2019.dockerfile | 83 +++---------------- ci/scripts/python_wheel_windows_build.bat | 19 +++-- ci/scripts/python_wheel_windows_test.bat | 14 +--- dev/tasks/python-wheels/github.windows.yml | 31 +++++-- dev/tasks/tasks.yml | 8 +- docker-compose.yml | 73 +++++++++++++--- 13 files changed, 371 insertions(+), 151 deletions(-) create mode 100644 ci/docker/python-free-threaded-wheel-windows-test-vs2019.dockerfile create mode 100644 ci/docker/python-free-threaded-wheel-windows-vs2019.dockerfile create mode 100644 ci/docker/python-wheel-windows-test-vs2019-base.dockerfile create mode 100644 ci/docker/python-wheel-windows-vs2019-base.dockerfile diff --git a/.env b/.env index 3db2673ae9594..252f59ccfb2e6 100644 --- a/.env +++ b/.env @@ -92,10 +92,11 @@ TZ=UTC VCPKG="943c5ef1c8f6b5e6ced092b242c8299caae2ff01" # 2024.04.26 Release # This must be updated when we update -# ci/docker/python-wheel-windows-vs2019.dockerfile. +# ci/docker/python-*-windows-*.dockerfile. # 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=2024-08-06 +PYTHON_WHEEL_WINDOWS_IMAGE_REVISION=2025-01-08 +PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION=2025-01-08 # Use conanio/${CONAN_BASE}:{CONAN_VERSION} for "docker compose run --rm conan". # See https://github.com/conan-io/conan-docker-tools#readme and diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 27823cae5fa28..e54fe2393cf3d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -39,7 +39,7 @@ repos: files: >- ( ?^ci/docker/conda-python-emscripten\.dockerfile$| - ?^ci/docker/python-wheel-windows-test-vs2019\.dockerfile$| + ?^ci/docker/python-.*-wheel-windows-test-vs2019.*\.dockerfile$| ) types: [] - repo: https://github.com/pycqa/flake8 diff --git a/ci/docker/python-free-threaded-wheel-windows-test-vs2019.dockerfile b/ci/docker/python-free-threaded-wheel-windows-test-vs2019.dockerfile new file mode 100644 index 0000000000000..4b972999b0475 --- /dev/null +++ b/ci/docker/python-free-threaded-wheel-windows-test-vs2019.dockerfile @@ -0,0 +1,52 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# NOTE: You must update PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION in .env +# when you update this file. + +ARG base +# https://github.com/hadolint/hadolint/wiki/DL3006 +# (Hadolint does not expand variables and thinks '${base}' is an untagged image) +# hadolint ignore=DL3006 +FROM ${base} + +ARG python=3.13 + +SHELL ["powershell", "-NoProfile", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] +RUN $filename = 'python-3.13.1-amd64.exe'; \ + $url = 'https://www.python.org/ftp/python/3.13.1/' + $filename; \ + Invoke-WebRequest -Uri $url -OutFile $filename; \ + Start-Process -FilePath $filename -ArgumentList '/quiet', 'Include_freethreaded=1' -Wait + +ENV PYTHON_CMD="py -${python}t" + +SHELL ["cmd", "/S", "/C"] +RUN %PYTHON_CMD% -m pip install -U pip setuptools + +COPY python/requirements-wheel-test.txt C:/arrow/python/ +# Cython and Pandas wheels for 3.13 free-threaded are not released yet +RUN %PYTHON_CMD% -m pip install \ + --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \ + --pre \ + --prefer-binary \ + -r C:/arrow/python/requirements-wheel-test.txt +# cffi-based tests would crash when importing cffi. +# hadolint ignore=DL3059 +RUN %PYTHON_CMD% -m pip uninstall -y cffi + +ENV PYTHON="${python}t" +ENV PYTHON_GIL=0 diff --git a/ci/docker/python-free-threaded-wheel-windows-vs2019.dockerfile b/ci/docker/python-free-threaded-wheel-windows-vs2019.dockerfile new file mode 100644 index 0000000000000..adbdccde71dfc --- /dev/null +++ b/ci/docker/python-free-threaded-wheel-windows-vs2019.dockerfile @@ -0,0 +1,49 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# NOTE: You must update PYTHON_WHEEL_WINDOWS_IMAGE_REVISION in .env +# when you update this file. + +ARG base +# https://github.com/hadolint/hadolint/wiki/DL3006 +# (Hadolint does not expand variables and thinks '${base}' is an untagged image) +# hadolint ignore=DL3006 +FROM ${base} + +ARG python=3.13 + +SHELL ["powershell", "-NoProfile", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] +RUN $filename = 'python-3.13.1-amd64.exe'; \ + $url = 'https://www.python.org/ftp/python/3.13.1/' + $filename; \ + Invoke-WebRequest -Uri $url -OutFile $filename; \ + Start-Process -FilePath $filename -ArgumentList '/quiet', 'Include_freethreaded=1' -Wait + +ENV PYTHON_CMD="py -${python}t" + +SHELL ["cmd", "/S", "/C"] +RUN %PYTHON_CMD% -m pip install -U pip setuptools + +COPY python/requirements-wheel-build.txt C:/arrow/python/ +# Cython wheels for 3.13 free-threaded are not released yet +RUN %PYTHON_CMD% -m pip install \ + --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple \ + --pre \ + --prefer-binary \ + cython +RUN %PYTHON_CMD% -m pip install -r C:/arrow/python/requirements-wheel-build.txt + +ENV PYTHON="${python}t" diff --git a/ci/docker/python-wheel-windows-test-vs2019-base.dockerfile b/ci/docker/python-wheel-windows-test-vs2019-base.dockerfile new file mode 100644 index 0000000000000..73a78da30b907 --- /dev/null +++ b/ci/docker/python-wheel-windows-test-vs2019-base.dockerfile @@ -0,0 +1,51 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# NOTE: You must update PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION in .env +# when you update this file. + +# based on mcr.microsoft.com/windows/servercore:ltsc2019 +# contains choco and vs2019 preinstalled +FROM abrarov/msvc-2019:2.11.0 + +# hadolint shell=cmd.exe + +# Add unix tools to path +RUN setx path "%path%;C:\Program Files\Git\usr\bin" + +# 1. Remove previous installations of Python from the base image +# NOTE: a more recent base image (tried with 2.12.1) comes with Python 3.9.7 +# and the MSI installers are failing to remove pip and tcl/tk "products" making +# the subsequent choco python installation step failing for installing Python +# version 3.9.* due to existing python version +# 2. Install Minio for S3 testing. +RUN wmic product where "name like 'python%%'" call uninstall /nointeractive && \ + rm -rf Python* && \ + curl https://dl.min.io/server/minio/release/windows-amd64/archive/minio.RELEASE.2024-09-13T20-26-02Z \ + --output "C:\Windows\Minio.exe" + +# Install archiver to extract xz archives (for timezone database). +# Install the GCS testbench using a well-known Python version. +# NOTE: cannot use pipx's `--fetch-missing-python` because of +# https://github.com/pypa/pipx/issues/1521, therefore download Python ourselves. +RUN choco install --no-progress -r -y archiver && \ + choco install -r -y --pre --no-progress python --version=3.11.9 +ENV PIPX_BIN_DIR=C:\\Windows\\ +ENV PIPX_PYTHON="C:\Python311\python.exe" +COPY ci/scripts/install_gcs_testbench.bat C:/arrow/ci/scripts/ +RUN call "C:\arrow\ci\scripts\install_gcs_testbench.bat" && \ + storage-testbench -h diff --git a/ci/docker/python-wheel-windows-test-vs2019.dockerfile b/ci/docker/python-wheel-windows-test-vs2019.dockerfile index 564bca329f3cb..f80e7ba0fe044 100644 --- a/ci/docker/python-wheel-windows-test-vs2019.dockerfile +++ b/ci/docker/python-wheel-windows-test-vs2019.dockerfile @@ -15,49 +15,31 @@ # specific language governing permissions and limitations # under the License. -# NOTE: You must update PYTHON_WHEEL_WINDOWS_IMAGE_REVISION in .env +# NOTE: You must update PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION in .env # when you update this file. -# based on mcr.microsoft.com/windows/servercore:ltsc2019 -# contains choco and vs2019 preinstalled -FROM abrarov/msvc-2019:2.11.0 +ARG base +# https://github.com/hadolint/hadolint/wiki/DL3006 +# (Hadolint does not expand variables and thinks '${base}' is an untagged image) +# hadolint ignore=DL3006 +FROM ${base} # hadolint shell=cmd.exe -# Add unix tools to path -RUN setx path "%path%;C:\Program Files\Git\usr\bin" - -# 1. Remove previous installations of python from the base image -# NOTE: a more recent base image (tried with 2.12.1) comes with python 3.9.7 -# and the msi installers are failing to remove pip and tcl/tk "products" making -# the subsequent choco python installation step failing for installing python -# version 3.9.* due to existing python version -# 2. Install Minio for S3 testing. -RUN wmic product where "name like 'python%%'" call uninstall /nointeractive && \ - rm -rf Python* && \ - curl https://dl.min.io/server/minio/release/windows-amd64/archive/minio.RELEASE.2024-09-13T20-26-02Z \ - --output "C:\Windows\Minio.exe" - -# Install the GCS testbench using a well-known Python version. -# NOTE: cannot use pipx's `--fetch-missing-python` because of -# https://github.com/pypa/pipx/issues/1521, therefore download Python ourselves. -RUN choco install -r -y --pre --no-progress python --version=3.11.9 -ENV PIPX_BIN_DIR=C:\\Windows\\ -ENV PIPX_PYTHON="C:\Python311\python.exe" -COPY ci/scripts/install_gcs_testbench.bat C:/arrow/ci/scripts/ -RUN call "C:\arrow\ci\scripts\install_gcs_testbench.bat" && \ - storage-testbench -h - # Define the full version number otherwise choco falls back to patch number 0 (3.9 => 3.9.0) ARG python=3.9 -RUN (if "%python%"=="3.9" setx PYTHON_VERSION "3.9.13") & \ - (if "%python%"=="3.10" setx PYTHON_VERSION "3.10.11") & \ - (if "%python%"=="3.11" setx PYTHON_VERSION "3.11.9") & \ - (if "%python%"=="3.12" setx PYTHON_VERSION "3.12.5") & \ - (if "%python%"=="3.13" setx PYTHON_VERSION "3.13.0-rc1") - -# Install archiver to extract xz archives -RUN choco install -r -y --pre --no-progress --force python --version=%PYTHON_VERSION% && \ - choco install --no-progress -r -y archiver +RUN (if "%python%"=="3.9" setx PYTHON_VERSION "3.9.13" && setx PYTHON_CMD "C:\Python39\python") & \ + (if "%python%"=="3.10" setx PYTHON_VERSION "3.10.11" && setx PYTHON_CMD "py -3.10") & \ + (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.8" && setx PYTHON_CMD "py -3.12") & \ + (if "%python%"=="3.13" setx PYTHON_VERSION "3.13.1" && setx PYTHON_CMD "py -3.13") + +# hadolint ignore=DL3059 +RUN choco install -r -y --pre --no-progress --force python --version=%PYTHON_VERSION% +# hadolint ignore=DL3059 +RUN %PYTHON_CMD% -m pip install -U pip setuptools + +COPY python/requirements-wheel-test.txt C:/arrow/python/ +RUN %PYTHON_CMD% -m pip install -r C:/arrow/python/requirements-wheel-test.txt ENV PYTHON=$python diff --git a/ci/docker/python-wheel-windows-vs2019-base.dockerfile b/ci/docker/python-wheel-windows-vs2019-base.dockerfile new file mode 100644 index 0000000000000..bd91f01bf9b6d --- /dev/null +++ b/ci/docker/python-wheel-windows-vs2019-base.dockerfile @@ -0,0 +1,79 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# NOTE: You must update PYTHON_WHEEL_WINDOWS_IMAGE_REVISION in .env +# when you update this file. + +# based on mcr.microsoft.com/windows/servercore:ltsc2019 +# contains choco and vs2019 preinstalled +FROM abrarov/msvc-2019:2.11.0 + +# Install CMake and Ninja +ARG cmake=3.31.2 +RUN choco install --no-progress -r -y cmake --version=%cmake% --installargs 'ADD_CMAKE_TO_PATH=System' && \ + choco install --no-progress -r -y gzip wget ninja + +# Add unix tools to path +RUN setx path "%path%;C:\Program Files\Git\usr\bin" + +# Install vcpkg +# +# Compiling vcpkg itself from a git tag doesn't work anymore since vcpkg has +# started to ship precompiled binaries for the vcpkg-tool. +ARG vcpkg +COPY ci/vcpkg/*.patch \ + ci/vcpkg/*windows*.cmake \ + arrow/ci/vcpkg/ +COPY ci/scripts/install_vcpkg.sh arrow/ci/scripts/ +ENV VCPKG_ROOT=C:\\vcpkg +RUN bash arrow/ci/scripts/install_vcpkg.sh /c/vcpkg %vcpkg% && \ + setx PATH "%PATH%;%VCPKG_ROOT%" + +# Configure vcpkg and install dependencies +# NOTE: use windows batch environment notation for build arguments in RUN +# statements but bash notation in ENV statements +# VCPKG_FORCE_SYSTEM_BINARIES=1 spare around ~750MB of image size if the system +# cmake's and ninja's versions are recent enough +ARG build_type=release +ENV CMAKE_BUILD_TYPE=${build_type} \ + VCPKG_OVERLAY_TRIPLETS=C:\\arrow\\ci\\vcpkg \ + VCPKG_DEFAULT_TRIPLET=amd64-windows-static-md-${build_type} \ + VCPKG_FEATURE_FLAGS="manifests" +COPY ci/vcpkg/vcpkg.json arrow/ci/vcpkg/ +# cannot use the S3 feature here because while aws-sdk-cpp=1.9.160 contains +# ssl related fixes as well as we can patch the vcpkg portfile to support +# arm machines it hits ARROW-15141 where we would need to fall back to 1.8.186 +# but we cannot patch those portfiles since vcpkg-tool handles the checkout of +# previous versions => use bundled S3 build +RUN vcpkg install \ + --clean-after-build \ + --x-install-root=%VCPKG_ROOT%\installed \ + --x-manifest-root=arrow/ci/vcpkg \ + --x-feature=flight \ + --x-feature=gcs \ + --x-feature=json \ + --x-feature=orc \ + --x-feature=parquet \ + --x-feature=s3 + +# Remove previous installations of Python from the base image +# NOTE: a more recent base image (tried with 2.12.1) comes with Python 3.9.7 +# and the MSI installers are failing to remove pip and tcl/tk "products" making +# the subsequent choco python installation step failing for installing Python +# version 3.9.* due to existing Python version +RUN wmic product where "name like 'python%%'" call uninstall /nointeractive && \ + rm -rf Python* diff --git a/ci/docker/python-wheel-windows-vs2019.dockerfile b/ci/docker/python-wheel-windows-vs2019.dockerfile index cc8c17efe474e..50e942fd6bd5c 100644 --- a/ci/docker/python-wheel-windows-vs2019.dockerfile +++ b/ci/docker/python-wheel-windows-vs2019.dockerfile @@ -18,79 +18,22 @@ # NOTE: You must update PYTHON_WHEEL_WINDOWS_IMAGE_REVISION in .env # when you update this file. -# based on mcr.microsoft.com/windows/servercore:ltsc2019 -# contains choco and vs2019 preinstalled -FROM abrarov/msvc-2019:2.11.0 - -# Install CMake and Ninja -ARG cmake=3.21.4 -RUN choco install --no-progress -r -y cmake --version=%cmake% --installargs 'ADD_CMAKE_TO_PATH=System' && \ - choco install --no-progress -r -y gzip wget ninja - -# Add unix tools to path -RUN setx path "%path%;C:\Program Files\Git\usr\bin" - -# Install vcpkg -# -# Compiling vcpkg itself from a git tag doesn't work anymore since vcpkg has -# started to ship precompiled binaries for the vcpkg-tool. -ARG vcpkg -COPY ci/vcpkg/*.patch \ - ci/vcpkg/*windows*.cmake \ - arrow/ci/vcpkg/ -COPY ci/scripts/install_vcpkg.sh arrow/ci/scripts/ -ENV VCPKG_ROOT=C:\\vcpkg -RUN bash arrow/ci/scripts/install_vcpkg.sh /c/vcpkg %vcpkg% && \ - setx PATH "%PATH%;%VCPKG_ROOT%" - -# Configure vcpkg and install dependencies -# NOTE: use windows batch environment notation for build arguments in RUN -# statements but bash notation in ENV statements -# VCPKG_FORCE_SYSTEM_BINARIES=1 spare around ~750MB of image size if the system -# cmake's and ninja's versions are recent enough -ARG build_type=release -ENV CMAKE_BUILD_TYPE=${build_type} \ - VCPKG_OVERLAY_TRIPLETS=C:\\arrow\\ci\\vcpkg \ - VCPKG_DEFAULT_TRIPLET=amd64-windows-static-md-${build_type} \ - VCPKG_FEATURE_FLAGS="manifests" -COPY ci/vcpkg/vcpkg.json arrow/ci/vcpkg/ -# cannot use the S3 feature here because while aws-sdk-cpp=1.9.160 contains -# ssl related fixes as well as we can patch the vcpkg portfile to support -# arm machines it hits ARROW-15141 where we would need to fall back to 1.8.186 -# but we cannot patch those portfiles since vcpkg-tool handles the checkout of -# previous versions => use bundled S3 build -RUN vcpkg install \ - --clean-after-build \ - --x-install-root=%VCPKG_ROOT%\installed \ - --x-manifest-root=arrow/ci/vcpkg \ - --x-feature=flight \ - --x-feature=gcs \ - --x-feature=json \ - --x-feature=orc \ - --x-feature=parquet \ - --x-feature=s3 - -# Remove previous installations of python from the base image -# NOTE: a more recent base image (tried with 2.12.1) comes with python 3.9.7 -# and the msi installers are failing to remove pip and tcl/tk "products" making -# the subsequent choco python installation step failing for installing python -# version 3.9.* due to existing python version -RUN wmic product where "name like 'python%%'" call uninstall /nointeractive && \ - rm -rf Python* +ARG base +FROM ${base} # Define the full version number otherwise choco falls back to patch number 0 (3.9 => 3.9.0) +# Note that Python 3.9 does not come with the "py" launcher ARG python=3.9 -RUN (if "%python%"=="3.9" setx PYTHON_VERSION "3.9.13" && setx PATH "%PATH%;C:\Python39;C:\Python39\Scripts") & \ - (if "%python%"=="3.10" setx PYTHON_VERSION "3.10.11" && setx PATH "%PATH%;C:\Python310;C:\Python310\Scripts") & \ - (if "%python%"=="3.11" setx PYTHON_VERSION "3.11.9" && setx PATH "%PATH%;C:\Python311;C:\Python311\Scripts") & \ - (if "%python%"=="3.12" setx PYTHON_VERSION "3.12.5" && setx PATH "%PATH%;C:\Python312;C:\Python312\Scripts") & \ - (if "%python%"=="3.13" setx PYTHON_VERSION "3.13.0-rc1" && setx PATH "%PATH%;C:\Python313;C:\Python313\Scripts") +RUN (if "%python%"=="3.9" setx PYTHON_VERSION "3.9.13" && setx PYTHON_CMD "C:\Python39\python") & \ + (if "%python%"=="3.10" setx PYTHON_VERSION "3.10.11" && setx PYTHON_CMD "py -3.10") & \ + (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.8" && setx PYTHON_CMD "py -3.12") & \ + (if "%python%"=="3.13" setx PYTHON_VERSION "3.13.1" && setx PYTHON_CMD "py -3.13") + RUN choco install -r -y --pre --no-progress python --version=%PYTHON_VERSION% -RUN python -m pip install -U pip setuptools +RUN %PYTHON_CMD% -m pip install -U pip setuptools -COPY python/requirements-wheel-build.txt arrow/python/ -RUN python -m pip install -r arrow/python/requirements-wheel-build.txt +COPY python/requirements-wheel-build.txt C:/arrow/python/ +RUN %PYTHON_CMD% -m pip install -r C:/arrow/python/requirements-wheel-build.txt -# For debugging purposes -# RUN wget --no-check-certificate https://github.com/lucasg/Dependencies/releases/download/v1.10/Dependencies_x64_Release.zip -# RUN unzip Dependencies_x64_Release.zip -d Dependencies && setx path "%path%;C:\Dependencies" +ENV PYTHON=${python} diff --git a/ci/scripts/python_wheel_windows_build.bat b/ci/scripts/python_wheel_windows_build.bat index 999f40980f5d2..9287d2471deec 100644 --- a/ci/scripts/python_wheel_windows_build.bat +++ b/ci/scripts/python_wheel_windows_build.bat @@ -19,6 +19,11 @@ echo "Building windows wheel..." +@REM List installed Pythons +py -0p + +%PYTHON_CMD% -m sysconfig || exit /B 1 + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" @echo on @@ -27,7 +32,7 @@ choco install -r -y --no-progress vcredist140 choco upgrade -r -y --no-progress vcredist140 dir C:\Windows\System32\msvcp140.dll -echo "=== (%PYTHON_VERSION%) Clear output directories and leftovers ===" +echo "=== (%PYTHON%) Clear output directories and leftovers ===" del /s /q C:\arrow-build del /s /q C:\arrow-dist del /s /q C:\arrow\python\dist @@ -35,7 +40,7 @@ del /s /q C:\arrow\python\build del /s /q C:\arrow\python\pyarrow\*.so del /s /q C:\arrow\python\pyarrow\*.so.* -echo "=== (%PYTHON_VERSION%) Building Arrow C++ libraries ===" +echo "=== (%PYTHON%) Building Arrow C++ libraries ===" set ARROW_ACERO=ON set ARROW_DATASET=ON set ARROW_FLIGHT=ON @@ -107,8 +112,9 @@ cmake ^ cmake --build . --config %CMAKE_BUILD_TYPE% --target install || exit /B 1 popd -echo "=== (%PYTHON_VERSION%) Building wheel ===" +echo "=== (%PYTHON%) Building wheel ===" set PYARROW_BUILD_TYPE=%CMAKE_BUILD_TYPE% +set PYARROW_BUILD_VERBOSE=1 set PYARROW_BUNDLE_ARROW_CPP=ON set PYARROW_CMAKE_GENERATOR=%CMAKE_GENERATOR% set PYARROW_WITH_ACERO=%ARROW_ACERO% @@ -131,7 +137,7 @@ pushd C:\arrow\python cp C:\Windows\System32\msvcp140.dll pyarrow\ @REM Build wheel -python setup.py bdist_wheel || exit /B 1 +%PYTHON_CMD% setup.py bdist_wheel || exit /B 1 @REM Repair the wheel with delvewheel @REM @@ -141,12 +147,13 @@ python setup.py bdist_wheel || exit /B 1 @REM @REM For now this requires a custom version of delvewheel: @REM https://github.com/adang1345/delvewheel/pull/59 -pip install https://github.com/pitrou/delvewheel/archive/refs/heads/fixes-for-arrow.zip || exit /B 1 +%PYTHON_CMD% -m pip install https://github.com/pitrou/delvewheel/archive/refs/heads/fixes-for-arrow.zip || exit /B 1 for /f %%i in ('dir dist\pyarrow-*.whl /B') do (set WHEEL_NAME=%cd%\dist\%%i) || exit /B 1 echo "Wheel name: %WHEEL_NAME%" -delvewheel repair -vv --mangle-only=msvcp140.dll --no-patch ^ +%PYTHON_CMD% -m delvewheel repair -vv ^ + --mangle-only=msvcp140.dll --no-patch ^ -w repaired_wheels %WHEEL_NAME% || exit /B 1 popd diff --git a/ci/scripts/python_wheel_windows_test.bat b/ci/scripts/python_wheel_windows_test.bat index 12d35216b1ca5..ffe8b388f93df 100755 --- a/ci/scripts/python_wheel_windows_test.bat +++ b/ci/scripts/python_wheel_windows_test.bat @@ -25,28 +25,19 @@ 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 set PYARROW_TEST_PARQUET=ON set PYARROW_TEST_PARQUET_ENCRYPTION=ON set PYARROW_TEST_SUBSTRAIT=ON set PYARROW_TEST_S3=ON set PYARROW_TEST_TENSORFLOW=ON -@REM Enable again once https://github.com/scipy/oldest-supported-numpy/pull/27 gets merged -@REM set PYARROW_TEST_PANDAS=ON - set ARROW_TEST_DATA=C:\arrow\testing\data set PARQUET_TEST_DATA=C:\arrow\cpp\submodules\parquet-testing\data @REM List installed Pythons py -0p -set PYTHON_CMD=py -%PYTHON% - -%PYTHON_CMD% -m pip install -U pip setuptools || exit /B 1 - -@REM Install testing dependencies -%PYTHON_CMD% -m pip install -r C:\arrow\python\requirements-wheel-test.txt || exit /B 1 - @REM Install the built wheels %PYTHON_CMD% -m pip install --no-index --find-links=C:\arrow\python\repaired_wheels pyarrow || exit /B 1 @@ -70,8 +61,9 @@ set PYTHON_CMD=py -%PYTHON% @rem Download IANA Timezone Database for ORC C++ curl https://cygwin.osuosl.org/noarch/release/tzdata/tzdata-2024a-1.tar.xz --output tzdata.tar.xz || exit /B mkdir %USERPROFILE%\Downloads\test\tzdata -arc unarchive tzdata.tar.xz %USERPROFILE%\Downloads\test\tzdata +arc unarchive tzdata.tar.xz %USERPROFILE%\Downloads\test\tzdata || exit /B set TZDIR=%USERPROFILE%\Downloads\test\tzdata\usr\share\zoneinfo +dir %TZDIR% @REM Execute unittest %PYTHON_CMD% -m pytest -r s --pyargs pyarrow || exit /B 1 diff --git a/dev/tasks/python-wheels/github.windows.yml b/dev/tasks/python-wheels/github.windows.yml index de0efedbff534..36b25e9819f27 100644 --- a/dev/tasks/python-wheels/github.windows.yml +++ b/dev/tasks/python-wheels/github.windows.yml @@ -26,6 +26,7 @@ jobs: env: # archery uses this environment variable PYTHON: "{{ python_version }}" + PYTHON_ABI_TAG: "{{ python_abi_tag }}" # this is a private repository at the moment (mostly because of licensing # consideration of windows images with visual studio), but anyone can # recreate the image by manually building it via: @@ -43,6 +44,19 @@ jobs: {{ macros.github_login_ghcr()|indent }} {{ macros.github_install_archery()|indent }} + - name: Prepare + shell: bash + run: | + case "${PYTHON_ABI_TAG}" in + *t) + test_image_prefix=python-free-threaded + ;; + *) + test_image_prefix=python + ;; + esac + echo "TEST_IMAGE_PREFIX=${test_image_prefix}" >> ${GITHUB_ENV} + - name: Build wheel shell: cmd run: | @@ -54,11 +68,11 @@ jobs: @rem We can remove this workaround once we find a way to use @rem pulled caches when build an image. echo on - archery docker pull --no-ignore-pull-failures python-wheel-windows-vs2019 + archery docker pull --no-ignore-pull-failures %TEST_IMAGE_PREFIX%-wheel-windows-vs2019 if errorlevel 1 ( - archery docker build --no-pull python-wheel-windows-vs2019 || exit /B 1 + archery docker build --no-pull %TEST_IMAGE_PREFIX%-wheel-windows-vs2019 || exit /B 1 ) - archery docker run --no-build -e SETUPTOOLS_SCM_PRETEND_VERSION={{ arrow.no_rc_version }} python-wheel-windows-vs2019 + archery docker run --no-build -e SETUPTOOLS_SCM_PRETEND_VERSION={{ arrow.no_rc_version }} %TEST_IMAGE_PREFIX%-wheel-windows-vs2019 - uses: actions/upload-artifact@v4 with: @@ -69,16 +83,21 @@ jobs: shell: cmd run: | cd arrow - archery docker run python-wheel-windows-test + archery docker pull --no-ignore-pull-failures %TEST_IMAGE_PREFIX%-wheel-windows-test + if errorlevel 1 ( + archery docker build --no-pull %TEST_IMAGE_PREFIX%-wheel-windows-test || exit /B 1 + ) + archery docker run %TEST_IMAGE_PREFIX%-wheel-windows-test {{ macros.github_upload_releases("arrow/python/repaired_wheels/*.whl")|indent }} {{ macros.github_upload_gemfury("arrow/python/repaired_wheels/*.whl")|indent }} {{ macros.github_upload_wheel_scientific_python("arrow/repaired_wheels/repaired_wheels/*.whl")|indent }} {% if arrow.is_default_branch() %} - - name: Push Docker Image + - name: Push Docker image shell: cmd run: | cd arrow - archery docker push python-wheel-windows-vs2019 + archery docker push %TEST_IMAGE_PREFIX%-wheel-windows-vs2019 + archery docker push %TEST_IMAGE_PREFIX%-wheel-windows-test {% endif %} diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml index 9f04d33f83ca0..f5b5ab53ebab5 100644 --- a/dev/tasks/tasks.yml +++ b/dev/tasks/tasks.yml @@ -445,19 +445,15 @@ tasks: {############################## Wheel Windows ################################} -# TODO: Remove this when there's NumPy wheels for Windows. -# See https://github.com/numpy/numpy/issues/26157 for more info. -{% if abi_tag != "cp313t" %} - - wheel-windows-{{ python_tag }}-amd64: + wheel-windows-{{ python_tag }}-{{ abi_tag }}-amd64: ci: github template: python-wheels/github.windows.yml params: python_version: "{{ python_version }}" + python_abi_tag: "{{ abi_tag }}" artifacts: - pyarrow-{no_rc_version}-{{ python_tag }}-{{ abi_tag }}-win_amd64.whl -{% endif %} {% endfor %} {############################ Python sdist ####################################} diff --git a/docker-compose.yml b/docker-compose.yml index bd9120956330d..5cb96e62c1163 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -176,8 +176,12 @@ x-hierarchy: - python-free-threaded-wheel-manylinux-test-imports - python-wheel-manylinux-test-unittests - python-free-threaded-wheel-manylinux-test-unittests - - python-wheel-windows-vs2019 - - python-wheel-windows-test + - python-wheel-windows-vs2019-base: + - python-wheel-windows-vs2019 + - python-free-threaded-wheel-windows-vs2019 + - python-wheel-windows-test-base: + - python-wheel-windows-test + - python-free-threaded-wheel-windows-test volumes: almalinux-ccache: @@ -1262,12 +1266,29 @@ services: CHECK_UNITTESTS: "ON" command: /arrow/ci/scripts/python_wheel_unix_test.sh /arrow + python-wheel-windows-vs2019-base: + image: ${REPO}:python-wheel-windows-vs2019-base-vcpkg-${VCPKG}-${PYTHON_WHEEL_WINDOWS_IMAGE_REVISION} + build: + args: + vcpkg: ${VCPKG} + context: . + dockerfile: ci/docker/python-wheel-windows-vs2019-base.dockerfile + # This should make the pushed images reusable, but the image gets rebuilt. + # Uncomment if no local cache is available. + # cache_from: + # - abrarov/msvc-2019:2.11.0 + # - ${REPO}:python-wheel-windows-vs2019-base-vcpkg-${VCPKG}-${PYTHON_WHEEL_WINDOWS_IMAGE_REVISION} + volumes: &python-wheel-windows-vs2019-volumes + - type: bind + source: . + target: "C:/arrow" + python-wheel-windows-vs2019: image: ${REPO}:python-${PYTHON}-wheel-windows-vs2019-vcpkg-${VCPKG}-${PYTHON_WHEEL_WINDOWS_IMAGE_REVISION} build: args: + base: ${REPO}:python-wheel-windows-vs2019-base-vcpkg-${VCPKG}-${PYTHON_WHEEL_WINDOWS_IMAGE_REVISION} python: ${PYTHON} - vcpkg: ${VCPKG} context: . dockerfile: ci/docker/python-wheel-windows-vs2019.dockerfile # This should make the pushed images reusable, but the image gets rebuilt. @@ -1275,23 +1296,51 @@ services: # cache_from: # - abrarov/msvc-2019:2.11.0 # - ${REPO}:python-${PYTHON}-wheel-windows-vs2019-vcpkg-${VCPKG}-${PYTHON_WHEEL_WINDOWS_IMAGE_REVISION} - volumes: - - type: bind - source: . - target: "C:/arrow" + volumes: *python-wheel-windows-vs2019-volumes command: arrow\\ci\\scripts\\python_wheel_windows_build.bat + python-free-threaded-wheel-windows-vs2019: + image: ${REPO}:python-${PYTHON}-free-threaded-wheel-windows-vs2019-vcpkg-${VCPKG}-${PYTHON_WHEEL_WINDOWS_IMAGE_REVISION} + build: + args: + base: ${REPO}:python-wheel-windows-vs2019-base-vcpkg-${VCPKG}-${PYTHON_WHEEL_WINDOWS_IMAGE_REVISION} + python: ${PYTHON} + context: . + dockerfile: ci/docker/python-free-threaded-wheel-windows-vs2019.dockerfile + # This should make the pushed images reusable, but the image gets rebuilt. + # Uncomment if no local cache is available. + # cache_from: + # - abrarov/msvc-2019:2.11.0 + # - ${REPO}:python-${PYTHON}-free-threaded-wheel-windows-vs2019-vcpkg-${VCPKG}-${PYTHON_WHEEL_WINDOWS_IMAGE_REVISION} + volumes: *python-wheel-windows-vs2019-volumes + command: arrow\\ci\\scripts\\python_wheel_windows_build.bat + + python-wheel-windows-test-base: + image: ${REPO}:python-wheel-windows-test-vs2019-base-${PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION} + build: + context: . + dockerfile: ci/docker/python-wheel-windows-test-vs2019-base.dockerfile + volumes: *python-wheel-windows-vs2019-volumes + python-wheel-windows-test: - image: ${REPO}:python-${PYTHON}-wheel-windows-test-vs2019-${PYTHON_WHEEL_WINDOWS_IMAGE_REVISION} + image: ${REPO}:python-${PYTHON}-wheel-windows-test-vs2019-${PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION} build: args: + base: ${REPO}:python-wheel-windows-test-vs2019-base-${PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION} python: ${PYTHON} context: . dockerfile: ci/docker/python-wheel-windows-test-vs2019.dockerfile - volumes: - - type: bind - source: . - target: "C:/arrow" + volumes: *python-wheel-windows-vs2019-volumes + command: arrow\\ci\\scripts\\python_wheel_windows_test.bat + + python-free-threaded-wheel-windows-test: + image: ${REPO}:python-${PYTHON}-free-threaded-wheel-windows-test-vs2019-${PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION} + build: + args: + base: ${REPO}:python-wheel-windows-test-vs2019-base-${PYTHON_WHEEL_WINDOWS_TEST_IMAGE_REVISION} + context: . + dockerfile: ci/docker/python-free-threaded-wheel-windows-test-vs2019.dockerfile + volumes: *python-wheel-windows-vs2019-volumes command: arrow\\ci\\scripts\\python_wheel_windows_test.bat ############################## Integration #################################