Skip to content

Commit

Permalink
Add Python 3.13
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco committed Nov 1, 2024
1 parent 5589e45 commit 0253740
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
From dd3c0fa3fd2795326dae0e0ed63c668f5506cf32 Mon Sep 17 00:00:00 2001
From: "J. Nick Koston" <[email protected]>
Date: Thu, 31 Oct 2024 14:05:40 -0500
Subject: [PATCH] gh-126156: Improve performance of creating `Morsel` objects
(#126157)

Replaces the manually constructed loop with a call to `dict.update`
---
Lib/http/cookies.py | 5 +++--
.../Library/2024-10-30-00-12-22.gh-issue-126156.BOSqv0.rst | 1 +
2 files changed, 4 insertions(+), 2 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2024-10-30-00-12-22.gh-issue-126156.BOSqv0.rst

diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py
index 6b9ed24ad8e..d7e8d08b2d9 100644
--- a/Lib/http/cookies.py
+++ b/Lib/http/cookies.py
@@ -266,6 +266,8 @@ class Morsel(dict):
"samesite" : "SameSite",
}

+ _reserved_defaults = dict.fromkeys(_reserved, "")
+
_flags = {'secure', 'httponly'}

def __init__(self):
@@ -273,8 +275,7 @@ def __init__(self):
self._key = self._value = self._coded_value = None

# Set default attributes
- for key in self._reserved:
- dict.__setitem__(self, key, "")
+ dict.update(self, self._reserved_defaults)

@property
def key(self):
--
2.39.3 (Apple Git-145)

131 changes: 131 additions & 0 deletions python/3.13/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
ARG BUILD_FROM
FROM $BUILD_FROM

ARG \
PYTHON_VERSION \
PIP_VERSION \
GPG_KEY \
QEMU_CPU

# ensure local python is preferred over distribution python
ENV PATH /usr/local/bin:$PATH

# Set shell
SHELL ["/bin/ash", "-o", "pipefail", "-c"]

COPY *.patch /usr/src/
RUN set -ex \
&& export PYTHON_VERSION=${PYTHON_VERSION} \
&& apk add --no-cache --virtual .fetch-deps \
gnupg \
openssl \
tar \
xz \
\
&& curl -L -o python.tar.xz "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz" \
&& curl -L -o python.tar.xz.asc "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc" \
&& export GNUPGHOME="$(mktemp -d)" \
&& echo "disable-ipv6" >> "$GNUPGHOME/dirmngr.conf" \
&& gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "${GPG_KEY}" \
&& gpg --batch --verify python.tar.xz.asc python.tar.xz \
&& { command -v gpgconf > /dev/null && gpgconf --kill all || :; } \
&& rm -rf "$GNUPGHOME" python.tar.xz.asc \
&& mkdir -p /usr/src/python \
&& tar -xJC /usr/src/python --strip-components=1 -f python.tar.xz \
&& rm python.tar.xz \
\
&& apk add --no-cache --virtual .build-deps \
patch \
bzip2-dev \
coreutils \
dpkg-dev dpkg \
expat-dev \
findutils \
build-base \
gdbm-dev \
libc-dev \
libffi-dev \
libnsl-dev \
openssl \
openssl-dev \
libtirpc-dev \
linux-headers \
make \
mpdecimal-dev \
ncurses-dev \
pax-utils \
readline-dev \
sqlite-dev \
tcl-dev \
tk \
tk-dev \
xz-dev \
zlib-dev \
bluez-dev \
# add build deps before removing fetch deps in case there's overlap
&& apk del .fetch-deps \
\
&& for i in /usr/src/*.patch; do \
patch -d /usr/src/python -p 1 < "${i}"; done \
&& cd /usr/src/python \
&& gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" \
&& ./configure \
--build="$gnuArch" \
--enable-loadable-sqlite-extensions \
--enable-optimizations \
--enable-option-checking=fatal \
--enable-shared \
--with-lto \
--with-system-libmpdec \
--with-system-expat \
--without-ensurepip \
--without-static-libpython \
&& make -j "$(nproc)" \
LDFLAGS="-Wl,--strip-all" \
CFLAGS="-fno-semantic-interposition -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" \
# set thread stack size to 1MB so we don't segfault before we hit sys.getrecursionlimit()
# https://github.com/alpinelinux/aports/commit/2026e1259422d4e0cf92391ca2d3844356c649d0
EXTRA_CFLAGS="-DTHREAD_STACK_SIZE=0x100000" \
&& make install \
\
&& find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec scanelf --needed --nobanner --format '%n#p' '{}' ';' \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
| xargs -rt apk add --no-cache --virtual .python-rundeps \
&& apk del .build-deps \
\
&& find /usr/local -depth \
\( \
-type d -a \( -name test -o -name tests \) \
\) -exec rm -rf '{}' + \
&& rm -rf /usr/src/python \
&& rm -f /usr/src/*.patch

# make some useful symlinks that are expected to exist
RUN cd /usr/local/bin \
&& ln -s idle3 idle \
&& ln -s pydoc3 pydoc \
&& ln -s python3 python \
&& ln -s python3-config python-config

RUN set -ex; \
\
apk add --no-cache --virtual .fetch-deps openssl; \
\
curl -L -o get-pip.py 'https://bootstrap.pypa.io/get-pip.py'; \
\
apk del .fetch-deps; \
\
python get-pip.py \
--disable-pip-version-check \
--no-cache-dir \
pip==${PIP_VERSION} \
; \
pip --version; \
\
find /usr/local -depth \
\( \
-type d -a \( -name test -o -name tests \) \
\) -exec rm -rf '{}' +; \
rm -f get-pip.py
17 changes: 17 additions & 0 deletions python/3.13/arm-alignment.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Author: Dave Jones <[email protected]>
Description: Use aligned access for _sha3 module on ARM.
--- a/Modules/_sha3/sha3module.c
+++ b/Modules/_sha3/sha3module.c
@@ -64,6 +64,12 @@
#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
#endif

+/* Bus error on 32-bit ARM due to un-aligned memory accesses; 64-bit ARM
+ * doesn't complain but un-aligned memory accesses are sub-optimal */
+#if defined(__arm__) || defined(__aarch64__)
+#define NO_MISALIGNED_ACCESSES
+#endif
+
/* mangle names */
#define KeccakF1600_FastLoop_Absorb _PySHA3_KeccakF1600_FastLoop_Absorb
#define Keccak_HashFinal _PySHA3_Keccak_HashFinal
16 changes: 16 additions & 0 deletions python/3.13/asynctio_unix_events.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index f34a5b4b44..b1d0f1e61e 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -369,6 +369,11 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
fut.set_result(total_sent)
return

+ # On 32-bit architectures truncate to 1GiB to avoid OverflowError,
+ # see bpo-38319.
+ if sys.maxsize < 2 ** 32:
+ blocksize = min(blocksize, 2 ** 30)
+
try:
sent = os.sendfile(fd, fileno, offset, blocksize)
except (BlockingIOError, InterruptedError):
17 changes: 17 additions & 0 deletions python/3.13/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
image: ghcr.io/home-assistant/{arch}-base-python
build_from:
aarch64: "ghcr.io/home-assistant/aarch64-base:"
armv7: "ghcr.io/home-assistant/armv7-base:"
armhf: "ghcr.io/home-assistant/armhf-base:"
amd64: "ghcr.io/home-assistant/amd64-base:"
i386: "ghcr.io/home-assistant/i386-base:"
cosign:
base_identity: https://github.com/home-assistant/docker-base/.*
identity: https://github.com/home-assistant/docker-base/.*
args:
PYTHON_VERSION: 3.13.0
PIP_VERSION: 24.2
GPG_KEY: 7169605F62C751356D054A26A821E680E5FA6305
labels:
io.hass.base.name: python
org.opencontainers.image.source: https://github.com/home-assistant/docker-base
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
From dd3c0fa3fd2795326dae0e0ed63c668f5506cf32 Mon Sep 17 00:00:00 2001
From: "J. Nick Koston" <[email protected]>
Date: Thu, 31 Oct 2024 14:05:40 -0500
Subject: [PATCH] gh-126156: Improve performance of creating `Morsel` objects
(#126157)

Replaces the manually constructed loop with a call to `dict.update`
---
Lib/http/cookies.py | 5 +++--
.../Library/2024-10-30-00-12-22.gh-issue-126156.BOSqv0.rst | 1 +
2 files changed, 4 insertions(+), 2 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2024-10-30-00-12-22.gh-issue-126156.BOSqv0.rst

diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py
index 6b9ed24ad8e..d7e8d08b2d9 100644
--- a/Lib/http/cookies.py
+++ b/Lib/http/cookies.py
@@ -266,6 +266,8 @@ class Morsel(dict):
"samesite" : "SameSite",
}

+ _reserved_defaults = dict.fromkeys(_reserved, "")
+
_flags = {'secure', 'httponly'}

def __init__(self):
@@ -273,8 +275,7 @@ def __init__(self):
self._key = self._value = self._coded_value = None

# Set default attributes
- for key in self._reserved:
- dict.__setitem__(self, key, "")
+ dict.update(self, self._reserved_defaults)

@property
def key(self):
--
2.39.3 (Apple Git-145)

45 changes: 45 additions & 0 deletions python/3.13/musl-find_library.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
diff -ru Python-2.7.12.orig/Lib/ctypes/util.py Python-2.7.12/Lib/ctypes/util.py
--- Python-2.7.12.orig/Lib/ctypes/util.py 2016-06-26 00:49:30.000000000 +0300
+++ Python-2.7.12/Lib/ctypes/util.py 2016-11-03 16:05:46.954665040 +0200
@@ -204,6 +204,41 @@
def find_library(name, is64 = False):
return _get_soname(_findLib_crle(name, is64) or _findLib_gcc(name))

+ elif True:
+
+ # Patched for Alpine Linux / musl - search manually system paths
+ def _is_elf(filepath):
+ try:
+ with open(filepath, 'rb') as fh:
+ return fh.read(4) == b'\x7fELF'
+ except:
+ return False
+
+ def find_library(name):
+ from glob import glob
+ # absolute name?
+ if os.path.isabs(name):
+ return name
+ # special case for libm, libcrypt and libpthread and musl
+ if name in ['m', 'crypt', 'pthread']:
+ name = 'c'
+ elif name in ['libm.so', 'libcrypt.so', 'libpthread.so']:
+ name = 'libc.so'
+ # search in standard locations (musl order)
+ paths = ['/lib', '/usr/local/lib', '/usr/lib']
+ if 'LD_LIBRARY_PATH' in os.environ:
+ paths = os.environ['LD_LIBRARY_PATH'].split(':') + paths
+ for d in paths:
+ f = os.path.join(d, name)
+ if _is_elf(f):
+ return os.path.basename(f)
+
+ prefix = os.path.join(d, 'lib'+name)
+ for suffix in ['.so', '.so.*']:
+ for f in glob('{0}{1}'.format(prefix, suffix)):
+ if _is_elf(f):
+ return os.path.basename(f)
+
else:

def _findSoname_ldconfig(name):

0 comments on commit 0253740

Please sign in to comment.