Skip to content

Commit 8c9c5ce

Browse files
committed
Add CPython 3.13 --disable-gil build
1 parent 7c41b1b commit 8c9c5ce

File tree

5 files changed

+47
-25
lines changed

5 files changed

+47
-25
lines changed

docker/Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ FROM build_cpython AS build_cpython313
144144
COPY build_scripts/cpython-pubkey-312-313.txt /build_scripts/cpython-pubkeys.txt
145145
RUN manylinux-entrypoint /build_scripts/build-cpython.sh 3.13.0a2
146146

147+
FROM build_cpython AS build_cpython313_nogil
148+
COPY build_scripts/cpython-pubkey-312-313.txt /build_scripts/cpython-pubkeys.txt
149+
RUN manylinux-entrypoint /build_scripts/build-cpython.sh 3.13.0a2 nogil
150+
147151
FROM build_cpython AS all_cpython
148152
COPY build_scripts/finalize-python.sh /build_scripts/
149153
RUN --mount=type=bind,target=/build_cpython36,from=build_cpython36 \
@@ -154,6 +158,7 @@ RUN --mount=type=bind,target=/build_cpython36,from=build_cpython36 \
154158
--mount=type=bind,target=/build_cpython311,from=build_cpython311 \
155159
--mount=type=bind,target=/build_cpython312,from=build_cpython312 \
156160
--mount=type=bind,target=/build_cpython313,from=build_cpython313 \
161+
--mount=type=bind,target=/build_cpython313_nogil,from=build_cpython313_nogil \
157162
mkdir -p /opt/_internal && \
158163
cp -rf /build_cpython*/opt/_internal/* /opt/_internal/ && \
159164
manylinux-entrypoint /build_scripts/finalize-python.sh

docker/build_scripts/build-cpython.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ pushd Python-${CPYTHON_VERSION}
3333
PREFIX="/opt/_internal/cpython-${CPYTHON_VERSION}"
3434
mkdir -p ${PREFIX}/lib
3535
CFLAGS_EXTRA=""
36+
CONFIGURE_ARGS=""
37+
38+
if [ "${2:-}" == "nogil" ]; then
39+
PREFIX="${PREFIX}-nogil"
40+
CONFIGURE_ARGS="--disable-gil"
41+
fi
42+
3643
if [ "${CPYTHON_VERSION}" == "3.6.15" ]; then
3744
# https://github.com/python/cpython/issues/89863
3845
# gcc-12+ uses these 2 flags in -O2 but they were only enabled in -O3 with gcc-11
@@ -48,7 +55,7 @@ fi
4855
./configure \
4956
CFLAGS_NODIST="${MANYLINUX_CFLAGS} ${MANYLINUX_CPPFLAGS} ${CFLAGS_EXTRA}" \
5057
LDFLAGS_NODIST="${MANYLINUX_LDFLAGS}" \
51-
--prefix=${PREFIX} --disable-shared --with-ensurepip=no > /dev/null
58+
--prefix=${PREFIX} --disable-shared --with-ensurepip=no ${CONFIGURE_ARGS} > /dev/null
5259
make > /dev/null
5360
make install > /dev/null
5461
popd

docker/build_scripts/finalize-one.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ if [ -e ${PREFIX}/bin/python3 ] && [ ! -e ${PREFIX}/bin/python ]; then
1515
fi
1616
PY_VER=$(${PREFIX}/bin/python -c "import sys; print('.'.join(str(v) for v in sys.version_info[:2]))")
1717
PY_IMPL=$(${PREFIX}/bin/python -c "import sys; print(sys.implementation.name)")
18+
PY_GIL=$(${PREFIX}/bin/python -c "import sysconfig; print('t' if sysconfig.get_config_vars().get('Py_GIL_DISABLED', 0) else '')")
1819

1920
# Install pinned packages for this python version.
2021
# Use the already intsalled cpython pip to bootstrap pip if available
@@ -32,6 +33,6 @@ ABI_TAG=$(${PREFIX}/bin/python ${MY_DIR}/python-tag-abi-tag.py)
3233
ln -s ${PREFIX} /opt/python/${ABI_TAG}
3334
# Make versioned python commands available directly in environment.
3435
if [[ "${PY_IMPL}" == "cpython" ]]; then
35-
ln -s ${PREFIX}/bin/python /usr/local/bin/python${PY_VER}
36+
ln -s ${PREFIX}/bin/python /usr/local/bin/python${PY_VER}${PY_GIL}
3637
fi
37-
ln -s ${PREFIX}/bin/python /usr/local/bin/${PY_IMPL}${PY_VER}
38+
ln -s ${PREFIX}/bin/python /usr/local/bin/${PY_IMPL}${PY_VER}${PY_GIL}

tests/run_tests.sh

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ else
1818
fi
1919

2020
if [ "${AUDITWHEEL_POLICY:0:10}" == "musllinux_" ]; then
21-
EXPECTED_PYTHON_COUNT=8
22-
EXPECTED_PYTHON_COUNT_ALL=8
21+
EXPECTED_PYTHON_COUNT=9
22+
EXPECTED_PYTHON_COUNT_ALL=9
2323
else
2424
if [ "${AUDITWHEEL_ARCH}" == "x86_64" ] || [ "${AUDITWHEEL_ARCH}" == "i686" ] || [ "${AUDITWHEEL_ARCH}" == "aarch64" ]; then
25-
EXPECTED_PYTHON_COUNT=12
26-
EXPECTED_PYTHON_COUNT_ALL=12
25+
EXPECTED_PYTHON_COUNT=13
26+
EXPECTED_PYTHON_COUNT_ALL=13
2727
else
28-
EXPECTED_PYTHON_COUNT=8
29-
EXPECTED_PYTHON_COUNT_ALL=8
28+
EXPECTED_PYTHON_COUNT=9
29+
EXPECTED_PYTHON_COUNT_ALL=9
3030
fi
3131
fi
3232
PYTHON_COUNT=$(manylinux-interpreters list --installed | wc -l)
@@ -58,27 +58,28 @@ for PYTHON in /opt/python/*/bin/python; do
5858
$PYTHON $MY_DIR/ssl-check.py
5959
IMPLEMENTATION=$(${PYTHON} -c "import sys; print(sys.implementation.name)")
6060
PYVERS=$(${PYTHON} -c "import sys; print('.'.join(map(str, sys.version_info[:2])))")
61+
PY_GIL=$(${PYTHON} -c "import sysconfig; print('t' if sysconfig.get_config_vars().get('Py_GIL_DISABLED', 0) else '')")
6162
if [ "${IMPLEMENTATION}" == "cpython" ]; then
6263
# Make sure sqlite3 module can be loaded properly and is the manylinux version one
6364
# c.f. https://github.com/pypa/manylinux/issues/1030
6465
$PYTHON -c 'import sqlite3; print(sqlite3.sqlite_version); assert sqlite3.sqlite_version_info[0:2] >= (3, 34)'
6566
# Make sure tkinter module can be loaded properly
6667
$PYTHON -c 'import tkinter; print(tkinter.TkVersion); assert tkinter.TkVersion >= 8.6'
6768
# cpython shall be available as python
68-
LINK_VERSION=$(python${PYVERS} -VV)
69+
LINK_VERSION=$(python${PYVERS}${PY_GIL} -VV)
6970
REAL_VERSION=$(${PYTHON} -VV)
7071
test "${LINK_VERSION}" = "${REAL_VERSION}"
7172
fi
7273
# cpythonX.Y / pypyX.Y shall be available directly in PATH
73-
LINK_VERSION=$(${IMPLEMENTATION}${PYVERS} -VV)
74+
LINK_VERSION=$(${IMPLEMENTATION}${PYVERS}${PY_GIL} -VV)
7475
REAL_VERSION=$(${PYTHON} -VV)
7576
test "${LINK_VERSION}" = "${REAL_VERSION}"
7677

7778
# check a simple project can be built
78-
SRC_DIR=/tmp/forty-two-${IMPLEMENTATION}${PYVERS}
79-
DIST_DIR=/tmp/dist-${IMPLEMENTATION}${PYVERS}
80-
cp -rf ${MY_DIR}/forty-two ${SRC_DIR}
8179
PY_ABI_TAGS=$(basename $(dirname $(dirname $PYTHON)))
80+
SRC_DIR=/tmp/forty-two-${PY_ABI_TAGS}
81+
DIST_DIR=/tmp/dist-${PY_ABI_TAGS}
82+
cp -rf ${MY_DIR}/forty-two ${SRC_DIR}
8283
EXPECTED_WHEEL_NAME=forty_two-0.1.0-${PY_ABI_TAGS}-linux_${AUDITWHEEL_ARCH}.whl
8384
${PYTHON} -m build -w -o ${DIST_DIR} ${SRC_DIR}
8485
if [ ! -f ${DIST_DIR}/${EXPECTED_WHEEL_NAME} ]; then

tools/update_native_dependencies.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import re
44
import subprocess
55

6+
from collections import defaultdict
67
from pathlib import Path
78

89
import requests
@@ -30,23 +31,30 @@ def _sha256(url):
3031

3132
def _update_cpython(dry_run):
3233
lines = DOCKERFILE.read_text().splitlines()
33-
re_ = re.compile(r"^RUN.*/build-cpython.sh (?P<version>.*)$")
34+
re_ = re.compile(r"^RUN.*/build-cpython.sh .*$")
35+
updates = defaultdict(list)
3436
for i in range(len(lines)):
3537
match = re_.match(lines[i])
3638
if match is None:
3739
continue
38-
current_version = Version(match["version"])
40+
version = lines[i].strip().split()[3]
41+
current_version = Version(version)
3942
latest_version = latest("python/cpython", major=f'{current_version.major}.{current_version.minor}', pre_ok=current_version.is_prerelease)
4043
if latest_version > current_version:
41-
root = f"Python-{latest_version}"
42-
url = f"https://www.python.org/ftp/python/{latest_version.major}.{latest_version.minor}.{latest_version.micro}"
43-
_sha256(f"{url}/{root}.tar.xz")
44-
lines[i] = lines[i].replace(match["version"], str(latest_version))
45-
message = f"Bump CPython {current_version}{latest_version}"
46-
print(message)
47-
if not dry_run:
48-
DOCKERFILE.write_text("\n".join(lines) + "\n")
49-
subprocess.check_call(["git", "commit", "-am", message])
44+
key = (version, str(latest_version))
45+
if len(updates[key]) == 0:
46+
root = f"Python-{latest_version}"
47+
url = f"https://www.python.org/ftp/python/{latest_version.major}.{latest_version.minor}.{latest_version.micro}"
48+
_sha256(f"{url}/{root}.tar.xz")
49+
updates[key].append(i)
50+
for key in updates:
51+
for i in updates[key]:
52+
lines[i] = lines[i].replace(key[0], key[1])
53+
message = f"Bump CPython {key[0]}{key[1]}"
54+
print(message)
55+
if not dry_run:
56+
DOCKERFILE.write_text("\n".join(lines) + "\n")
57+
subprocess.check_call(["git", "commit", "-am", message])
5058

5159

5260
def _update_with_root(tool, dry_run):

0 commit comments

Comments
 (0)