Skip to content

Commit f54c98e

Browse files
lesteveogrisel
andauthored
CI Add Windows free-threaded wheel (#30313)
Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org>
1 parent 96b53ad commit f54c98e

File tree

3 files changed

+68
-37
lines changed

3 files changed

+68
-37
lines changed

.github/workflows/wheels.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ jobs:
7373
- os: windows-latest
7474
python: 313
7575
platform_id: win_amd64
76+
- os: windows-latest
77+
python: 313t
78+
platform_id: win_amd64
79+
free_threaded_support: True
7680

7781
# Linux 64 bit manylinux2014
7882
- os: ubuntu-latest

build_tools/github/build_minimal_windows_image.sh

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,49 @@ set -x
55

66
PYTHON_VERSION=$1
77

8-
TEMP_FOLDER="$HOME/AppData/Local/Temp"
9-
WHEEL_PATH=$(ls -d $TEMP_FOLDER/**/*/repaired_wheel/*)
10-
WHEEL_NAME=$(basename $WHEEL_PATH)
11-
12-
cp $WHEEL_PATH $WHEEL_NAME
13-
14-
# Dot the Python version for identifying the base Docker image
15-
PYTHON_DOCKER_IMAGE_PART=$(echo ${PYTHON_VERSION:0:1}.${PYTHON_VERSION:1:2})
16-
17-
if [[ "$CIBW_PRERELEASE_PYTHONS" =~ [tT]rue ]]; then
18-
PYTHON_DOCKER_IMAGE_PART="${PYTHON_DOCKER_IMAGE_PART}-rc"
8+
FREE_THREADED_BUILD="$(python -c"import sysconfig; print(bool(sysconfig.get_config_var('Py_GIL_DISABLED')))")"
9+
10+
if [[ $FREE_THREADED_BUILD == "False" ]]; then
11+
# Prepare a minimal Windows environement without any developer runtime libraries
12+
# installed to check that the scikit-learn wheel does not implicitly rely on
13+
# external DLLs when running the tests.
14+
TEMP_FOLDER="$HOME/AppData/Local/Temp"
15+
WHEEL_PATH=$(ls -d $TEMP_FOLDER/**/*/repaired_wheel/*)
16+
WHEEL_NAME=$(basename $WHEEL_PATH)
17+
18+
cp $WHEEL_PATH $WHEEL_NAME
19+
20+
# Dot the Python version for identifying the base Docker image
21+
PYTHON_DOCKER_IMAGE_PART=$(echo ${PYTHON_VERSION:0:1}.${PYTHON_VERSION:1:2})
22+
23+
if [[ "$CIBW_PRERELEASE_PYTHONS" =~ [tT]rue ]]; then
24+
PYTHON_DOCKER_IMAGE_PART="${PYTHON_DOCKER_IMAGE_PART}-rc"
25+
fi
26+
27+
# We could have all of the following logic in a Dockerfile but it's a lot
28+
# easier to do it in bash rather than figure out how to do it in Powershell
29+
# inside the Dockerfile ...
30+
DOCKER_IMAGE="winamd64/python:${PYTHON_DOCKER_IMAGE_PART}-windowsservercore"
31+
MNT_FOLDER="C:/mnt"
32+
CONTAINER_ID=$(docker run -it -v "$(cygpath -w $PWD):$MNT_FOLDER" -d $DOCKER_IMAGE)
33+
34+
function exec_inside_container() {
35+
docker exec $CONTAINER_ID powershell -Command $1
36+
}
37+
38+
exec_inside_container "python -m pip install $MNT_FOLDER/$WHEEL_NAME"
39+
exec_inside_container "python -m pip install $CIBW_TEST_REQUIRES"
40+
41+
# Save container state to scikit-learn/minimal-windows image. On Windows the
42+
# container needs to be stopped first.
43+
docker stop $CONTAINER_ID
44+
docker commit $CONTAINER_ID scikit-learn/minimal-windows
45+
else
46+
# This is too cumbersome to use a Docker image in the free-threaded case
47+
# TODO Remove the next three lines when scipy and pandas each have a release
48+
# with a Windows free-threaded wheel.
49+
python -m pip install numpy
50+
dev_anaconda_url=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple
51+
python -m pip install --pre --upgrade --timeout=60 --extra-index $dev_anaconda_url scipy pandas --only-binary :all:
52+
python -m pip install $CIBW_TEST_REQUIRES
1953
fi
20-
21-
# We could have all of the following logic in a Dockerfile but it's a lot
22-
# easier to do it in bash rather than figure out how to do it in Powershell
23-
# inside the Dockerfile ...
24-
DOCKER_IMAGE="winamd64/python:${PYTHON_DOCKER_IMAGE_PART}-windowsservercore"
25-
MNT_FOLDER="C:/mnt"
26-
CONTAINER_ID=$(docker run -it -v "$(cygpath -w $PWD):$MNT_FOLDER" -d $DOCKER_IMAGE)
27-
28-
function exec_inside_container() {
29-
docker exec $CONTAINER_ID powershell -Command $1
30-
}
31-
32-
exec_inside_container "python -m pip install $MNT_FOLDER/$WHEEL_NAME"
33-
exec_inside_container "python -m pip install $CIBW_TEST_REQUIRES"
34-
35-
# Save container state to scikit-learn/minimal-windows image. On Windows the
36-
# container needs to be stopped first.
37-
docker stop $CONTAINER_ID
38-
docker commit $CONTAINER_ID scikit-learn/minimal-windows

build_tools/github/test_windows_wheels.sh

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,23 @@ PROJECT_DIR=$2
88

99
python $PROJECT_DIR/build_tools/wheels/check_license.py
1010

11-
docker container run \
12-
--rm scikit-learn/minimal-windows \
13-
powershell -Command "python -c 'import sklearn; sklearn.show_versions()'"
11+
FREE_THREADED_BUILD="$(python -c"import sysconfig; print(bool(sysconfig.get_config_var('Py_GIL_DISABLED')))")"
1412

15-
docker container run \
16-
-e SKLEARN_SKIP_NETWORK_TESTS=1 \
17-
--rm scikit-learn/minimal-windows \
18-
powershell -Command "pytest --pyargs sklearn"
13+
if [[ $FREE_THREADED_BUILD == "False" ]]; then
14+
# Run the tests for the scikit-learn wheel in a minimal Windows environment
15+
# without any developer runtime libraries installed to ensure that it does not
16+
# implicitly rely on the presence of the DLLs of such runtime libraries.
17+
docker container run \
18+
--rm scikit-learn/minimal-windows \
19+
powershell -Command "python -c 'import sklearn; sklearn.show_versions()'"
20+
21+
docker container run \
22+
-e SKLEARN_SKIP_NETWORK_TESTS=1 \
23+
--rm scikit-learn/minimal-windows \
24+
powershell -Command "pytest --pyargs sklearn"
25+
else
26+
# This is too cumbersome to use a Docker image in the free-threaded case
27+
export PYTHON_GIL=0
28+
python -c "import sklearn; sklearn.show_versions()"
29+
pytest --pyargs sklearn
30+
fi

0 commit comments

Comments
 (0)