Skip to content

Commit

Permalink
Add CPython 3.13 --disable-gil build
Browse files Browse the repository at this point in the history
  • Loading branch information
mayeut committed Mar 13, 2024
1 parent 07a669e commit 565c5ca
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 25 deletions.
5 changes: 5 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ FROM build_cpython AS build_cpython313
COPY build_scripts/cpython-pubkey-312-313.txt /build_scripts/cpython-pubkeys.txt
RUN manylinux-entrypoint /build_scripts/build-cpython.sh 3.13.0a2

FROM build_cpython AS build_cpython313_nogil
COPY build_scripts/cpython-pubkey-312-313.txt /build_scripts/cpython-pubkeys.txt
RUN manylinux-entrypoint /build_scripts/build-cpython.sh 3.13.0a2 nogil

FROM build_cpython AS all_cpython
COPY build_scripts/finalize-python.sh /build_scripts/
RUN --mount=type=bind,target=/build_cpython36,from=build_cpython36 \
Expand All @@ -154,6 +158,7 @@ RUN --mount=type=bind,target=/build_cpython36,from=build_cpython36 \
--mount=type=bind,target=/build_cpython311,from=build_cpython311 \
--mount=type=bind,target=/build_cpython312,from=build_cpython312 \
--mount=type=bind,target=/build_cpython313,from=build_cpython313 \
--mount=type=bind,target=/build_cpython313_nogil,from=build_cpython313_nogil \
mkdir -p /opt/_internal && \
cp -rf /build_cpython*/opt/_internal/* /opt/_internal/ && \
manylinux-entrypoint /build_scripts/finalize-python.sh
Expand Down
9 changes: 8 additions & 1 deletion docker/build_scripts/build-cpython.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ pushd Python-${CPYTHON_VERSION}
PREFIX="/opt/_internal/cpython-${CPYTHON_VERSION}"
mkdir -p ${PREFIX}/lib
CFLAGS_EXTRA=""
CONFIGURE_ARGS=""

if [ "${2:-}" == "nogil" ]; then
PREFIX="${PREFIX}-nogil"
CONFIGURE_ARGS="--disable-gil"
fi

if [ "${CPYTHON_VERSION}" == "3.6.15" ]; then
# https://github.com/python/cpython/issues/89863
# gcc-12+ uses these 2 flags in -O2 but they were only enabled in -O3 with gcc-11
Expand All @@ -48,7 +55,7 @@ fi
./configure \
CFLAGS_NODIST="${MANYLINUX_CFLAGS} ${MANYLINUX_CPPFLAGS} ${CFLAGS_EXTRA}" \
LDFLAGS_NODIST="${MANYLINUX_LDFLAGS}" \
--prefix=${PREFIX} --disable-shared --with-ensurepip=no > /dev/null
--prefix=${PREFIX} --disable-shared --with-ensurepip=no ${CONFIGURE_ARGS} > /dev/null
make > /dev/null
make install > /dev/null
popd
Expand Down
5 changes: 3 additions & 2 deletions docker/build_scripts/finalize-one.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ if [ -e ${PREFIX}/bin/python3 ] && [ ! -e ${PREFIX}/bin/python ]; then
fi
PY_VER=$(${PREFIX}/bin/python -c "import sys; print('.'.join(str(v) for v in sys.version_info[:2]))")
PY_IMPL=$(${PREFIX}/bin/python -c "import sys; print(sys.implementation.name)")
PY_GIL=$(${PREFIX}/bin/python -c "import sysconfig; print('t' if sysconfig.get_config_vars().get('Py_GIL_DISABLED', 0) else '')")

# Install pinned packages for this python version.
# Use the already intsalled cpython pip to bootstrap pip if available
Expand All @@ -32,6 +33,6 @@ ABI_TAG=$(${PREFIX}/bin/python ${MY_DIR}/python-tag-abi-tag.py)
ln -s ${PREFIX} /opt/python/${ABI_TAG}
# Make versioned python commands available directly in environment.
if [[ "${PY_IMPL}" == "cpython" ]]; then
ln -s ${PREFIX}/bin/python /usr/local/bin/python${PY_VER}
ln -s ${PREFIX}/bin/python /usr/local/bin/python${PY_VER}${PY_GIL}
fi
ln -s ${PREFIX}/bin/python /usr/local/bin/${PY_IMPL}${PY_VER}
ln -s ${PREFIX}/bin/python /usr/local/bin/${PY_IMPL}${PY_VER}${PY_GIL}
23 changes: 12 additions & 11 deletions tests/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ else
fi

if [ "${AUDITWHEEL_POLICY:0:10}" == "musllinux_" ]; then
EXPECTED_PYTHON_COUNT=8
EXPECTED_PYTHON_COUNT_ALL=8
EXPECTED_PYTHON_COUNT=9
EXPECTED_PYTHON_COUNT_ALL=9
else
if [ "${AUDITWHEEL_ARCH}" == "x86_64" ] || [ "${AUDITWHEEL_ARCH}" == "i686" ] || [ "${AUDITWHEEL_ARCH}" == "aarch64" ]; then
EXPECTED_PYTHON_COUNT=12
EXPECTED_PYTHON_COUNT_ALL=12
EXPECTED_PYTHON_COUNT=13
EXPECTED_PYTHON_COUNT_ALL=13
else
EXPECTED_PYTHON_COUNT=8
EXPECTED_PYTHON_COUNT_ALL=8
EXPECTED_PYTHON_COUNT=9
EXPECTED_PYTHON_COUNT_ALL=9
fi
fi
PYTHON_COUNT=$(manylinux-interpreters list --installed | wc -l)
Expand Down Expand Up @@ -58,27 +58,28 @@ for PYTHON in /opt/python/*/bin/python; do
$PYTHON $MY_DIR/ssl-check.py
IMPLEMENTATION=$(${PYTHON} -c "import sys; print(sys.implementation.name)")
PYVERS=$(${PYTHON} -c "import sys; print('.'.join(map(str, sys.version_info[:2])))")
PY_GIL=$(${PYTHON} -c "import sysconfig; print('t' if sysconfig.get_config_vars().get('Py_GIL_DISABLED', 0) else '')")
if [ "${IMPLEMENTATION}" == "cpython" ]; then
# Make sure sqlite3 module can be loaded properly and is the manylinux version one
# c.f. https://github.com/pypa/manylinux/issues/1030
$PYTHON -c 'import sqlite3; print(sqlite3.sqlite_version); assert sqlite3.sqlite_version_info[0:2] >= (3, 34)'
# Make sure tkinter module can be loaded properly
$PYTHON -c 'import tkinter; print(tkinter.TkVersion); assert tkinter.TkVersion >= 8.6'
# cpython shall be available as python
LINK_VERSION=$(python${PYVERS} -VV)
LINK_VERSION=$(python${PYVERS}${PY_GIL} -VV)
REAL_VERSION=$(${PYTHON} -VV)
test "${LINK_VERSION}" = "${REAL_VERSION}"
fi
# cpythonX.Y / pypyX.Y shall be available directly in PATH
LINK_VERSION=$(${IMPLEMENTATION}${PYVERS} -VV)
LINK_VERSION=$(${IMPLEMENTATION}${PYVERS}${PY_GIL} -VV)
REAL_VERSION=$(${PYTHON} -VV)
test "${LINK_VERSION}" = "${REAL_VERSION}"

# check a simple project can be built
SRC_DIR=/tmp/forty-two-${IMPLEMENTATION}${PYVERS}
DIST_DIR=/tmp/dist-${IMPLEMENTATION}${PYVERS}
cp -rf ${MY_DIR}/forty-two ${SRC_DIR}
PY_ABI_TAGS=$(basename $(dirname $(dirname $PYTHON)))
SRC_DIR=/tmp/forty-two-${PY_ABI_TAGS}
DIST_DIR=/tmp/dist-${PY_ABI_TAGS}
cp -rf ${MY_DIR}/forty-two ${SRC_DIR}
EXPECTED_WHEEL_NAME=forty_two-0.1.0-${PY_ABI_TAGS}-linux_${AUDITWHEEL_ARCH}.whl
${PYTHON} -m build -w -o ${DIST_DIR} ${SRC_DIR}
if [ ! -f ${DIST_DIR}/${EXPECTED_WHEEL_NAME} ]; then
Expand Down
30 changes: 19 additions & 11 deletions tools/update_native_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import re
import subprocess

from collections import defaultdict
from pathlib import Path

import requests
Expand Down Expand Up @@ -30,23 +31,30 @@ def _sha256(url):

def _update_cpython(dry_run):
lines = DOCKERFILE.read_text().splitlines()
re_ = re.compile(r"^RUN.*/build-cpython.sh (?P<version>.*)$")
re_ = re.compile(r"^RUN.*/build-cpython.sh .*$")
updates = defaultdict(list)
for i in range(len(lines)):
match = re_.match(lines[i])
if match is None:
continue
current_version = Version(match["version"])
version = lines[i].strip().split()[3]
current_version = Version(version)
latest_version = latest("python/cpython", major=f'{current_version.major}.{current_version.minor}', pre_ok=current_version.is_prerelease)
if latest_version > current_version:
root = f"Python-{latest_version}"
url = f"https://www.python.org/ftp/python/{latest_version.major}.{latest_version.minor}.{latest_version.micro}"
_sha256(f"{url}/{root}.tar.xz")
lines[i] = lines[i].replace(match["version"], str(latest_version))
message = f"Bump CPython {current_version}{latest_version}"
print(message)
if not dry_run:
DOCKERFILE.write_text("\n".join(lines) + "\n")
subprocess.check_call(["git", "commit", "-am", message])
key = (version, str(latest_version))
if len(updates[key]) == 0:
root = f"Python-{latest_version}"
url = f"https://www.python.org/ftp/python/{latest_version.major}.{latest_version.minor}.{latest_version.micro}"
_sha256(f"{url}/{root}.tar.xz")
updates[key].append(i)
for key in updates:
for i in updates[key]:
lines[i] = lines[i].replace(key[0], key[1])
message = f"Bump CPython {key[0]}{key[1]}"
print(message)
if not dry_run:
DOCKERFILE.write_text("\n".join(lines) + "\n")
subprocess.check_call(["git", "commit", "-am", message])


def _update_with_root(tool, dry_run):
Expand Down

0 comments on commit 565c5ca

Please sign in to comment.