From fe33e63812ce0758cf8c179afb8558a52d7d296c Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Thu, 12 Jun 2025 18:21:57 -0500
Subject: [PATCH 01/72] Use the latest patch for the CFLAGS JIT configuration
(#659)
---
cpython-unix/build-cpython.sh | 3 +-
cpython-unix/patch-jit-cflags-314.patch | 46 +++++++++++++++++--------
2 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index 820b6a2..75f330d 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -653,7 +653,8 @@ fi
# We patched configure.ac above. Reflect those changes.
autoconf
-CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS LDFLAGS=$LDFLAGS \
+# Ensure `CFLAGS` are propagated to JIT compilation for 3.13+
+CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS JIT_CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS \
./configure ${CONFIGURE_FLAGS}
# Supplement produced Makefile with our modifications.
diff --git a/cpython-unix/patch-jit-cflags-314.patch b/cpython-unix/patch-jit-cflags-314.patch
index 3a16fb5..a75563b 100644
--- a/cpython-unix/patch-jit-cflags-314.patch
+++ b/cpython-unix/patch-jit-cflags-314.patch
@@ -1,5 +1,12 @@
+diff --git a/Misc/NEWS.d/next/Build/2025-05-19-18-09-20.gh-issue-134273.ZAliyy.rst b/Misc/NEWS.d/next/Build/2025-05-19-18-09-20.gh-issue-134273.ZAliyy.rst
+new file mode 100644
+index 00000000000..3eb13cefbe6
+--- /dev/null
++++ b/Misc/NEWS.d/next/Build/2025-05-19-18-09-20.gh-issue-134273.ZAliyy.rst
+@@ -0,0 +1 @@
++Add support for configuring compiler flags for the JIT with ``CFLAGS_JIT``
diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py
-index d0a1c081ffe..deb83f275d2 100644
+index d0a1c081ffe..b383e39da19 100644
--- a/Tools/jit/_targets.py
+++ b/Tools/jit/_targets.py
@@ -10,6 +10,7 @@
@@ -18,16 +25,25 @@ index d0a1c081ffe..deb83f275d2 100644
known_symbols: dict[str, int] = dataclasses.field(default_factory=dict)
pyconfig_dir: pathlib.Path = pathlib.Path.cwd().resolve()
-@@ -120,6 +122,7 @@ async def _compile(
- ) -> _stencils.StencilGroup:
- o = tempdir / f"{opname}.o"
- args = [
+@@ -62,6 +64,7 @@ def _compute_digest(self) -> str:
+ hasher = hashlib.sha256()
+ hasher.update(self.triple.encode())
+ hasher.update(self.debug.to_bytes())
++ hasher.update(self.cflags.encode())
+ # These dependencies are also reflected in _JITSources in regen.targets:
+ hasher.update(PYTHON_EXECUTOR_CASES_C_H.read_bytes())
+ hasher.update((self.pyconfig_dir / "pyconfig.h").read_bytes())
+@@ -155,6 +158,8 @@ async def _compile(
+ f"{o}",
+ f"{c}",
+ *self.args,
++ # Allow user-provided CFLAGS to override any defaults
+ *shlex.split(self.cflags),
- f"--target={self.triple}",
- "-DPy_BUILD_CORE_MODULE",
- "-D_DEBUG" if self.debug else "-DNDEBUG",
+ ]
+ await _llvm.run("clang", args, echo=self.verbose)
+ return await self._parse(o)
diff --git a/Tools/jit/build.py b/Tools/jit/build.py
-index 1afd0c76bad..96c4cb07593 100644
+index 1afd0c76bad..a0733005929 100644
--- a/Tools/jit/build.py
+++ b/Tools/jit/build.py
@@ -39,11 +39,15 @@
@@ -35,19 +51,19 @@ index 1afd0c76bad..96c4cb07593 100644
"-v", "--verbose", action="store_true", help="echo commands as they are run"
)
+ parser.add_argument(
-+ "--with-cflags", help="additional flags to pass to the compiler", default=""
++ "--cflags", help="additional flags to pass to the compiler", default=""
+ )
args = parser.parse_args()
for target in args.target:
target.debug = args.debug
target.force = args.force
target.verbose = args.verbose
-+ target.cflags = args.with_cflags
++ target.cflags = args.cflags
target.pyconfig_dir = args.pyconfig_dir
target.build(
comment=comment,
diff --git a/configure b/configure
-index 884f8a4b068..2e6740c33d9 100755
+index 029bf527da4..fef9f2d7da9 100755
--- a/configure
+++ b/configure
@@ -10863,7 +10863,7 @@ then :
@@ -55,12 +71,12 @@ index 884f8a4b068..2e6740c33d9 100755
else case e in #(
e) as_fn_append CFLAGS_NODIST " $jit_flags"
- REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir ."
-+ REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --with-cflags=\"\$(CONFIGURE_CFLAGS)\""
++ REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --cflags=\"$CFLAGS_JIT\""
JIT_STENCILS_H="jit_stencils.h"
if test "x$Py_DEBUG" = xtrue
then :
diff --git a/configure.ac b/configure.ac
-index cf25148bad2..f8bfab7bf96 100644
+index 371b2e8ed73..cc37a636c52 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2776,7 +2776,7 @@ AS_VAR_IF([jit_flags],
@@ -68,7 +84,7 @@ index cf25148bad2..f8bfab7bf96 100644
[AS_VAR_APPEND([CFLAGS_NODIST], [" $jit_flags"])
AS_VAR_SET([REGEN_JIT_COMMAND],
- ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir ."])
-+ ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --with-cflags=\"\$(CONFIGURE_CFLAGS)\""])
++ ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --cflags=\"$CFLAGS_JIT\""])
AS_VAR_SET([JIT_STENCILS_H], ["jit_stencils.h"])
AS_VAR_IF([Py_DEBUG],
[true],
From cb5ec0b456d7b929119cd9a8ad3fdca0f55e0115 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Fri, 13 Jun 2025 09:14:45 -0500
Subject: [PATCH 02/72] Fix `CFLAGS_JIT` declaration (#660)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Silly typo in #659 — turns out macOS is where it fails with the wrong
flags, not Linux
---
cpython-unix/build-cpython.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index 75f330d..2296f2b 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -654,7 +654,7 @@ fi
autoconf
# Ensure `CFLAGS` are propagated to JIT compilation for 3.13+
-CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS JIT_CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS \
+CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS CFLAGS_JIT=$CFLAGS LDFLAGS=$LDFLAGS \
./configure ${CONFIGURE_FLAGS}
# Supplement produced Makefile with our modifications.
From 69f53e2028a75d4c1d26de0bc5476d86fcae8836 Mon Sep 17 00:00:00 2001
From: Jack O'Connor
Date: Tue, 10 Jun 2025 19:34:19 -0700
Subject: [PATCH 03/72] patch libedit to stop re-broadcasting signals
---
cpython-unix/build-libedit.sh | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/cpython-unix/build-libedit.sh b/cpython-unix/build-libedit.sh
index 08387ec..6122059 100755
--- a/cpython-unix/build-libedit.sh
+++ b/cpython-unix/build-libedit.sh
@@ -82,6 +82,32 @@ index 614795f..4671f1b 100755
fi
EOF
+# When libedit receives a signal, it re-broadcasts it to its entire pgroup.
+# This seems intended to preserve normal ^C behavior in "raw" mode when the
+# terminal's ISIG flag is cleared? However, libedit does not in fact clear
+# ISIG. (And Jack can't find any evidence of any version that ever did.) This
+# sometimes results in the parent process receiving ^C twice back-to-back,
+# depending on the vagaries of signal coalescing. More pathologically, if the
+# parent tries to signal the child directly with e.g. `kill(pid, SIGTERM)`,
+# libedit *signals the parent right back* (not to mention any other pgroup
+# siblings or grandparents). This is just wild behavior, even though it's
+# probably rare that it matters in practice. Patch it out. See also:
+# https://github.com/astral-sh/uv/issues/13919#issuecomment-2960501229.
+patch -p1 << "EOF"
+diff --git i/src/sig.c w/src/sig.c
+index d2b77e7..884b2dd 100644
+--- i/src/sig.c
++++ w/src/sig.c
+@@ -107,7 +107,7 @@ sig_handler(int signo)
+ sel->el_signal->sig_action[i].sa_flags = 0;
+ sigemptyset(&sel->el_signal->sig_action[i].sa_mask);
+ (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+- (void) kill(0, signo);
++ (void) raise(signo);
+ errno = save_errno;
+ }
+EOF
+
cflags="${EXTRA_TARGET_CFLAGS} -fPIC -I${TOOLS_PATH}/deps/include -I${TOOLS_PATH}/deps/include/ncursesw"
ldflags="${EXTRA_TARGET_LDFLAGS} -L${TOOLS_PATH}/deps/lib"
From 45f514c647b755d9d90f218b2bdbe6765cc5ecbd Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Wed, 18 Jun 2025 11:13:29 -0500
Subject: [PATCH 04/72] Use Depot runners for Windows builds (#664)
Goes from a range of 26-32m -> 15->23m
---
ci-runners.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/ci-runners.yaml b/ci-runners.yaml
index aeb0e5c..e8d9f5a 100644
--- a/ci-runners.yaml
+++ b/ci-runners.yaml
@@ -26,6 +26,11 @@ macos-latest:
platform: darwin
free: true
+depot-windows-2022-8:
+ arch: x86_64
+ platform: windows
+ free: false
+
windows-latest-large:
arch: x86_64
platform: windows
From 4c3dfd82929a3dc199a1e93a62589598e8271631 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Thu, 26 Jun 2025 15:57:38 -0500
Subject: [PATCH 05/72] Bump to CPython 3.14.0b3 (#663)
---
cpython-unix/build-cpython.sh | 25 ++++++++++++-------
.../patch-static-remote-debug-3.14.patch | 22 ----------------
pythonbuild/downloads.py | 8 +++---
3 files changed, 20 insertions(+), 35 deletions(-)
delete mode 100644 cpython-unix/patch-static-remote-debug-3.14.patch
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index 2296f2b..ce88e6c 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -90,12 +90,6 @@ else
patch -p1 -i ${ROOT}/patch-xopen-source-ios-legacy.patch
fi
-# See https://github.com/python/cpython/pull/135146
-# TODO(zanieb): Drop in 3.14b3
-if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]; then
- patch -p1 -i ${ROOT}/patch-static-remote-debug-3.14.patch
-fi
-
# LIBTOOL_CRUFT is unused and breaks cross-compiling on macOS. Nuke it.
# Submitted upstream at https://github.com/python/cpython/pull/101048.
if [ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_11}" ]; then
@@ -485,7 +479,9 @@ if [ -n "${CPYTHON_OPTIMIZED}" ]; then
fi
# Respect CFLAGS during JIT compilation.
- # Backports https://github.com/python/cpython/pull/134276
+ #
+ # Backports https://github.com/python/cpython/pull/134276 which we're trying to get released
+ # in 3.14, but is currently only in 3.15+.
if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]; then
patch -p1 -i ${ROOT}/patch-jit-cflags-314.patch
elif [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then
@@ -653,8 +649,19 @@ fi
# We patched configure.ac above. Reflect those changes.
autoconf
-# Ensure `CFLAGS` are propagated to JIT compilation for 3.13+
-CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS CFLAGS_JIT=$CFLAGS LDFLAGS=$LDFLAGS \
+# Ensure `CFLAGS` are propagated to JIT compilation for 3.13+ (note this variable has no effect on
+# 3.12 and earlier)
+CFLAGS_JIT="${CFLAGS}"
+
+# In 3.14+, the JIT compiler on x86-64 Linux uses a model that conflicts with `-fPIC`, so strip it
+# from the flags. See:
+# - https://github.com/python/cpython/issues/135690
+# - https://github.com/python/cpython/pull/130097
+if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" && "${TARGET_TRIPLE}" == x86_64* ]]; then
+ CFLAGS_JIT="${CFLAGS_JIT//-fPIC/}"
+fi
+
+CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS CFLAGS_JIT=$CFLAGS_JIT LDFLAGS=$LDFLAGS \
./configure ${CONFIGURE_FLAGS}
# Supplement produced Makefile with our modifications.
diff --git a/cpython-unix/patch-static-remote-debug-3.14.patch b/cpython-unix/patch-static-remote-debug-3.14.patch
deleted file mode 100644
index 1c359c3..0000000
--- a/cpython-unix/patch-static-remote-debug-3.14.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-diff --git a/Python/remote_debug.h b/Python/remote_debug.h
-index 6cbf1c8deaa..ab494ea71da 100644
---- a/Python/remote_debug.h
-+++ b/Python/remote_debug.h
-@@ -131,7 +131,7 @@ _Py_RemoteDebug_FreePageCache(proc_handle_t *handle)
- }
- }
-
--void
-+static void
- _Py_RemoteDebug_ClearCache(proc_handle_t *handle)
- {
- for (int i = 0; i < MAX_PAGES; i++) {
-@@ -989,7 +989,7 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address
- #endif
- }
-
--int
-+static int
- _Py_RemoteDebug_PagedReadRemoteMemory(proc_handle_t *handle,
- uintptr_t addr,
- size_t size,
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index f59afd8..3e7adc8 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -82,10 +82,10 @@
"python_tag": "cp313",
},
"cpython-3.14": {
- "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0b2.tar.xz",
- "size": 23579860,
- "sha256": "7ac9e84844bbc0a5a8f1f79a37a68b3b8caf2a58b4aa5999c49227cb36e70ea6",
- "version": "3.14.0b2",
+ "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0b3.tar.xz",
+ "size": 23626928,
+ "sha256": "c6f48bf51f01f50d87007a445dd7afe4a4c7a87ab482570be924c1ddfd0d3682",
+ "version": "3.14.0b3",
"licenses": ["Python-2.0", "CNRI-Python"],
"license_file": "LICENSE.cpython.txt",
"python_tag": "cp314",
From 97c36a3df31e7a9130f769992eb928f410605c11 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Fri, 27 Jun 2025 22:12:26 -0500
Subject: [PATCH 06/72] Add ARM64 Windows builds for Python 3.11+ (#387)
Picking up https://github.com/indygreg/python-build-standalone/pull/93
---------
Co-authored-by: Adrian Antkowiak
---
.github/workflows/windows.yml | 1 +
ci-runners.yaml | 5 ++
ci-targets.yaml | 18 +++++
cpython-windows/build.py | 129 ++++++++++++++++++++++++++--------
src/validation.rs | 26 +++++--
5 files changed, 143 insertions(+), 36 deletions(-)
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index a7535c6..ad8bbfe 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -92,6 +92,7 @@ jobs:
fi
build:
+ timeout-minutes: 60
needs:
- generate-matrix
- pythonbuild
diff --git a/ci-runners.yaml b/ci-runners.yaml
index e8d9f5a..43ff941 100644
--- a/ci-runners.yaml
+++ b/ci-runners.yaml
@@ -40,3 +40,8 @@ windows-latest:
arch: x86_64
platform: windows
free: true
+
+windows-11-arm:
+ arch: aarch64
+ platform: windows
+ free: false
diff --git a/ci-targets.yaml b/ci-targets.yaml
index 70078e8..c7b4bd1 100644
--- a/ci-targets.yaml
+++ b/ci-targets.yaml
@@ -384,3 +384,21 @@ windows:
- options:
- freethreaded+pgo
minimum-python-version: "3.13"
+
+ aarch64-pc-windows-msvc:
+ arch: aarch64
+ vcvars: vcvarsamd64_arm64.bat
+ python_versions:
+ # On 3.9 / 3.10, `_tkinter` is failing to be included in the build
+ # - "3.9"
+ # - "3.10"
+ - "3.11"
+ - "3.12"
+ - "3.13"
+ - "3.14"
+ build_options:
+ - pgo
+ build_options_conditional:
+ - options:
+ - freethreaded+pgo
+ minimum-python-version: "3.13"
diff --git a/cpython-windows/build.py b/cpython-windows/build.py
index 15b0a44..0df651e 100644
--- a/cpython-windows/build.py
+++ b/cpython-windows/build.py
@@ -370,7 +370,7 @@ def hack_props(
mpdecimal_version = DOWNLOADS["mpdecimal"]["version"]
- if meets_python_minimum_version(python_version, "3.14"):
+ if meets_python_minimum_version(python_version, "3.14") or arch == "arm64":
tcltk_commit = DOWNLOADS["tk-windows-bin"]["git_commit"]
else:
tcltk_commit = DOWNLOADS["tk-windows-bin-8612"]["git_commit"]
@@ -464,6 +464,8 @@ def hack_props(
suffix = b"-x64"
elif arch == "win32":
suffix = b""
+ elif arch == "arm64":
+ suffix = b""
else:
raise Exception("unhandled architecture: %s" % arch)
@@ -505,6 +507,7 @@ def hack_project_files(
build_directory: str,
python_version: str,
zlib_entry: str,
+ arch: str,
):
"""Hacks Visual Studio project files to work with our build."""
@@ -518,6 +521,17 @@ def hack_project_files(
zlib_entry,
)
+ # `--include-tcltk` is forced off on arm64, undo that
+ # See https://github.com/python/cpython/pull/132650
+ try:
+ static_replace_in_file(
+ cpython_source_path / "PC" / "layout" / "main.py",
+ rb'if ns.arch in ("arm32", "arm64"):',
+ rb'if ns.arch == "arm32":',
+ )
+ except NoSearchStringError:
+ pass
+
# Our SQLite directory is named weirdly. This throws off version detection
# in the project file. Replace the parsing logic with a static string.
sqlite3_version = DOWNLOADS["sqlite"]["actual_version"].encode("ascii")
@@ -603,14 +617,18 @@ def hack_project_files(
# have a standalone zlib DLL, so we remove references to it. For Python
# 3.14+, we're using tk-windows-bin 8.6.14 which includes a prebuilt zlib
# DLL, so we skip this patch there.
- if meets_python_minimum_version(
- python_version, "3.12"
- ) and meets_python_maximum_version(python_version, "3.13"):
- static_replace_in_file(
- pcbuild_path / "_tkinter.vcxproj",
- rb'<_TclTkDLL Include="$(tcltkdir)\bin\$(tclZlibDllName)" />',
- rb"",
- )
+ # On arm64, we use the new version of tk-windows-bin for all versions.
+ if meets_python_minimum_version(python_version, "3.12") and (
+ meets_python_maximum_version(python_version, "3.13") or arch == "arm64"
+ ):
+ try:
+ static_replace_in_file(
+ pcbuild_path / "_tkinter.vcxproj",
+ rb'<_TclTkDLL Include="$(tcltkdir)\bin\$(tclZlibDllName)" />',
+ rb"",
+ )
+ except NoSearchStringError:
+ pass
# We don't need to produce python_uwp.exe and its *w variant. Or the
# python3.dll, pyshellext, or pylauncher.
@@ -730,9 +748,11 @@ def build_openssl_for_arch(
elif arch == "amd64":
configure = "VC-WIN64A"
prefix = "64"
+ elif arch == "arm64":
+ configure = "VC-WIN64-ARM"
+ prefix = "arm64"
else:
- print("invalid architecture: %s" % arch)
- sys.exit(1)
+ raise Exception("unhandled architecture: %s" % arch)
# The official CPython OpenSSL builds hack ms/uplink.c to change the
# ``GetModuleHandle(NULL)`` invocation to load things from _ssl.pyd
@@ -780,6 +800,12 @@ def build_openssl_for_arch(
log("copying %s to %s" % (source, dest))
shutil.copyfile(source, dest)
+ # Copy `applink.c` to the include directory.
+ source_applink = source_root / "ms" / "applink.c"
+ dest_applink = install_root / "include" / "openssl" / "applink.c"
+ log("copying %s to %s" % (source_applink, dest_applink))
+ shutil.copyfile(source_applink, dest_applink)
+
def build_openssl(
entry: str,
@@ -801,6 +827,7 @@ def build_openssl(
root_32 = td / "x86"
root_64 = td / "x64"
+ root_arm64 = td / "arm64"
if arch == "x86":
root_32.mkdir()
@@ -824,13 +851,28 @@ def build_openssl(
root_64,
jom_archive=jom_archive,
)
+ elif arch == "arm64":
+ root_arm64.mkdir()
+ build_openssl_for_arch(
+ perl_path,
+ "arm64",
+ openssl_archive,
+ openssl_version,
+ nasm_archive,
+ root_arm64,
+ jom_archive=jom_archive,
+ )
else:
- raise ValueError("unhandled arch: %s" % arch)
+ raise Exception("unhandled architecture: %s" % arch)
install = td / "out"
if arch == "x86":
shutil.copytree(root_32 / "install" / "32", install / "openssl" / "win32")
+ elif arch == "arm64":
+ shutil.copytree(
+ root_arm64 / "install" / "arm64", install / "openssl" / "arm64"
+ )
else:
shutil.copytree(root_64 / "install" / "64", install / "openssl" / "amd64")
@@ -901,9 +943,14 @@ def build_libffi(
if arch == "x86":
args.append("-x86")
artifacts_path = ffi_source_path / "i686-pc-cygwin"
- else:
+ elif arch == "arm64":
+ args.append("-arm64")
+ artifacts_path = ffi_source_path / "aarch64-w64-cygwin"
+ elif arch == "amd64":
args.append("-x64")
artifacts_path = ffi_source_path / "x86_64-w64-cygwin"
+ else:
+ raise Exception("unhandled architecture: %s" % arch)
subprocess.run(args, env=env, check=True)
@@ -1069,8 +1116,10 @@ def find_additional_dependencies(project: pathlib.Path):
abi_platform = "win_amd64"
elif arch == "win32":
abi_platform = "win32"
+ elif arch == "arm64":
+ abi_platform = "win_arm64"
else:
- raise ValueError("unhandled arch: %s" % arch)
+ raise Exception("unhandled architecture: %s" % arch)
if freethreaded:
abi_tag = ".cp%st-%s" % (python_majmin, abi_platform)
@@ -1171,8 +1220,8 @@ def find_additional_dependencies(project: pathlib.Path):
if name == "zlib":
name = zlib_entry
- # On 3.14+, we use the latest tcl/tk version
- if ext == "_tkinter" and python_majmin == "314":
+ # On 3.14+ and aarch64, we use the latest tcl/tk version
+ if ext == "_tkinter" and (python_majmin == "314" or arch == "arm64"):
name = name.replace("-8612", "")
download_entry = DOWNLOADS[name]
@@ -1258,16 +1307,18 @@ def build_cpython(
setuptools_wheel = download_entry("setuptools", BUILD)
pip_wheel = download_entry("pip", BUILD)
- # On CPython 3.14+, we use the latest tcl/tk version which has additional runtime
- # dependencies, so we are conservative and use the old version elsewhere.
- if meets_python_minimum_version(python_version, "3.14"):
- tk_bin_archive = download_entry(
- "tk-windows-bin", BUILD, local_name="tk-windows-bin.tar.gz"
- )
- else:
- tk_bin_archive = download_entry(
- "tk-windows-bin-8612", BUILD, local_name="tk-windows-bin.tar.gz"
- )
+ # On CPython 3.14+, we use the latest tcl/tk version which has additional
+ # runtime dependencies, so we are conservative and use the old version
+ # elsewhere. The old version isn't built for arm64, so we use the new
+ # version there too
+ tk_bin_entry = (
+ "tk-windows-bin"
+ if meets_python_minimum_version(python_version, "3.14") or arch == "arm64"
+ else "tk-windows-bin-8612"
+ )
+ tk_bin_archive = download_entry(
+ tk_bin_entry, BUILD, local_name="tk-windows-bin.tar.gz"
+ )
# On CPython 3.14+, zstd is included
if meets_python_minimum_version(python_version, "3.14"):
@@ -1297,8 +1348,11 @@ def build_cpython(
elif arch == "x86":
build_platform = "win32"
build_directory = "win32"
+ elif arch == "arm64":
+ build_platform = "arm64"
+ build_directory = "arm64"
else:
- raise ValueError("unhandled arch: %s" % arch)
+ raise Exception("unhandled architecture: %s" % arch)
tempdir_opts = (
{"ignore_cleanup_errors": True} if sys.version_info >= (3, 12) else {}
@@ -1332,7 +1386,7 @@ def build_cpython(
# We need all the OpenSSL library files in the same directory to appease
# install rules.
- openssl_arch = {"amd64": "amd64", "x86": "win32"}[arch]
+ openssl_arch = {"amd64": "amd64", "x86": "win32", "arm64": "arm64"}[arch]
openssl_root = td / "openssl" / openssl_arch
openssl_bin_path = openssl_root / "bin"
openssl_lib_path = openssl_root / "lib"
@@ -1346,6 +1400,17 @@ def build_cpython(
log("copying %s to %s" % (source, dest))
shutil.copyfile(source, dest)
+ # Delete the tk nmake helper, it's not needed and links msvc
+ tcltk_commit: str = DOWNLOADS[tk_bin_entry]["git_commit"]
+ tcltk_path = td / ("cpython-bin-deps-%s" % tcltk_commit)
+ (
+ tcltk_path
+ / build_directory
+ / "lib"
+ / "nmake"
+ / "x86_64-w64-mingw32-nmakehlp.exe"
+ ).unlink()
+
cpython_source_path = td / ("Python-%s" % python_version)
pcbuild_path = cpython_source_path / "PCbuild"
@@ -1368,6 +1433,7 @@ def build_cpython(
build_directory,
python_version=python_version,
zlib_entry=zlib_entry,
+ arch=arch,
)
if pgo:
@@ -1790,9 +1856,14 @@ def main() -> None:
if os.environ.get("Platform") == "x86":
target_triple = "i686-pc-windows-msvc"
arch = "x86"
- else:
+ elif os.environ.get("Platform") == "arm64":
+ target_triple = "aarch64-pc-windows-msvc"
+ arch = "arm64"
+ elif os.environ.get("Platform") == "x64":
target_triple = "x86_64-pc-windows-msvc"
arch = "amd64"
+ else:
+ raise Exception("unhandled architecture: %s" % os.environ.get("Platform"))
# TODO need better dependency checking.
diff --git a/src/validation.rs b/src/validation.rs
index 19aace0..9084754 100644
--- a/src/validation.rs
+++ b/src/validation.rs
@@ -18,7 +18,7 @@ use {
macho::{LoadCommandVariant, MachHeader, Nlist},
pe::{ImageNtHeaders, PeFile, PeFile32, PeFile64},
},
- Endianness, FileKind, Object, SectionIndex, SymbolScope,
+ Architecture, Endianness, FileKind, Object, SectionIndex, SymbolScope,
},
once_cell::sync::Lazy,
std::{
@@ -33,6 +33,7 @@ use {
const RECOGNIZED_TRIPLES: &[&str] = &[
"aarch64-apple-darwin",
"aarch64-apple-ios",
+ "aarch64-pc-windows-msvc",
"aarch64-unknown-linux-gnu",
"armv7-unknown-linux-gnueabi",
"armv7-unknown-linux-gnueabihf",
@@ -117,11 +118,13 @@ const PE_ALLOWED_LIBRARIES: &[&str] = &[
"libcrypto-1_1.dll",
"libcrypto-1_1-x64.dll",
"libcrypto-3.dll",
+ "libcrypto-3-arm64.dll",
"libcrypto-3-x64.dll",
"libffi-8.dll",
"libssl-1_1.dll",
"libssl-1_1-x64.dll",
"libssl-3.dll",
+ "libssl-3-arm64.dll",
"libssl-3-x64.dll",
"python3.dll",
"python39.dll",
@@ -137,8 +140,14 @@ const PE_ALLOWED_LIBRARIES: &[&str] = &[
"tk86t.dll",
];
-// CPython 3.14 uses tcl/tk 8.6.14+ which includes a bundled zlib and dynamically links to msvcrt.
-const PE_ALLOWED_LIBRARIES_314: &[&str] = &["msvcrt.dll", "zlib1.dll"];
+// CPython 3.14 and ARM64 use a newer version of tcl/tk (8.6.14+) which includes a bundled zlib that
+// dynamically links some system libraries
+const PE_ALLOWED_LIBRARIES_314: &[&str] = &[
+ "zlib1.dll",
+ "api-ms-win-crt-private-l1-1-0.dll", // zlib loads this library on arm64, 3.14+
+ "msvcrt.dll", // zlib loads this library
+];
+const PE_ALLOWED_LIBRARIES_ARM64: &[&str] = &["msvcrt.dll", "zlib1.dll"];
static GLIBC_MAX_VERSION_BY_TRIPLE: Lazy>> =
Lazy::new(|| {
@@ -496,6 +505,7 @@ static PLATFORM_TAG_BY_TRIPLE: Lazy> = Lazy:
[
("aarch64-apple-darwin", "macosx-11.0-arm64"),
("aarch64-apple-ios", "iOS-aarch64"),
+ ("aarch64-pc-windows-msvc", "win-arm64"),
("aarch64-unknown-linux-gnu", "linux-aarch64"),
("armv7-unknown-linux-gnueabi", "linux-arm"),
("armv7-unknown-linux-gnueabihf", "linux-arm"),
@@ -1375,15 +1385,17 @@ fn validate_pe<'data, Pe: ImageNtHeaders>(
let lib = String::from_utf8(lib.to_vec())?;
match python_major_minor {
- "3.9" | "3.10" | "3.11" | "3.12" | "3.13" => {}
+ "3.11" | "3.12" | "3.13" if pe.architecture() == Architecture::Aarch64 => {
+ if PE_ALLOWED_LIBRARIES_ARM64.contains(&lib.as_str()) {
+ continue;
+ }
+ }
"3.14" => {
if PE_ALLOWED_LIBRARIES_314.contains(&lib.as_str()) {
continue;
}
}
- _ => {
- panic!("unhandled Python version: {}", python_major_minor);
- }
+ _ => {}
}
if !PE_ALLOWED_LIBRARIES.contains(&lib.as_str()) {
From 240b6392a544070b5e0ab3c4b8c5c620a880186e Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Sat, 28 Jun 2025 09:33:48 -0500
Subject: [PATCH 07/72] Gate `x86_64-w64-mingw32-nmakehlp.exe` removal to
builds where it is present (#671)
Fixes
https://github.com/astral-sh/python-build-standalone/actions/runs/15939854940/job/44966313482
---
cpython-windows/build.py | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/cpython-windows/build.py b/cpython-windows/build.py
index 0df651e..3b0c3b4 100644
--- a/cpython-windows/build.py
+++ b/cpython-windows/build.py
@@ -1401,15 +1401,16 @@ def build_cpython(
shutil.copyfile(source, dest)
# Delete the tk nmake helper, it's not needed and links msvc
- tcltk_commit: str = DOWNLOADS[tk_bin_entry]["git_commit"]
- tcltk_path = td / ("cpython-bin-deps-%s" % tcltk_commit)
- (
- tcltk_path
- / build_directory
- / "lib"
- / "nmake"
- / "x86_64-w64-mingw32-nmakehlp.exe"
- ).unlink()
+ if tk_bin_entry == "tk-windows-bin":
+ tcltk_commit: str = DOWNLOADS[tk_bin_entry]["git_commit"]
+ tcltk_path = td / ("cpython-bin-deps-%s" % tcltk_commit)
+ (
+ tcltk_path
+ / build_directory
+ / "lib"
+ / "nmake"
+ / "x86_64-w64-mingw32-nmakehlp.exe"
+ ).unlink()
cpython_source_path = td / ("Python-%s" % python_version)
pcbuild_path = cpython_source_path / "PCbuild"
From 526189db29aac2ab097fbbb0b28b589a21247c2d Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Sat, 28 Jun 2025 11:22:07 -0500
Subject: [PATCH 08/72] Generate the Docker CI matrix (#672)
I think this will be a useful precursor to
https://github.com/astral-sh/python-build-standalone/pull/670
---
.github/workflows/linux.yml | 43 ++++++------
.github/workflows/macos.yml | 8 ++-
.github/workflows/windows.yml | 8 ++-
ci-matrix.py | 126 +++++++++++++++++++++++++---------
4 files changed, 126 insertions(+), 59 deletions(-)
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 3b70b5f..6f73a95 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -54,14 +54,9 @@ jobs:
- generate-matrix
strategy:
fail-fast: false
- matrix:
- image:
- - build
- - build.cross
- - build.cross-riscv64
- - gcc
- name: ${{ matrix.image }}
- runs-on: depot-ubuntu-22.04
+ matrix: ${{ fromJson(needs.generate-matrix.outputs.docker-build-matrix) }}
+ name: ${{ matrix.name }}
+ runs-on: ${{ matrix.runner }}
permissions:
packages: write
steps:
@@ -95,37 +90,38 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
- file: build/${{ matrix.image }}.Dockerfile
+ file: build/${{ matrix.name }}.Dockerfile
labels: org.opencontainers.image.source=https://github.com/${{ env.REPO_NAME }}
# Cache from/to the current branch of the current repo as the primary cache key.
# Cache from the default branch of the current repo so branches can have cache hits.
# Cache from the default branch of the canonical repo so forks can have cache hits.
# Ignore errors on cache writes so CI of forks works without a valid GHCR config.
cache-from: |
- type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-${{ env.GIT_REF_NAME }}
- type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-main
- type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.image }}-main
+ type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-${{ env.GIT_REF_NAME }}
+ type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-main
+ type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.name }}-main
cache-to: |
- type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.image }}-${{ env.GIT_REF_NAME }},ignore-error=true
+ type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-${{ env.GIT_REF_NAME }},ignore-error=true
outputs: |
- type=docker,dest=build/image-${{ matrix.image }}.tar
+ type=docker,dest=build/image-${{ matrix.name }}.tar
- name: Compress Image
run: |
- echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.image }}
+ echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.name }}
zstd -v -T0 -6 --rm build/image-*.tar
- name: Upload Docker Image
uses: actions/upload-artifact@v4
with:
- name: image-${{ matrix.image }}
+ name: image-${{ matrix.name }}
path: build/image-*
generate-matrix:
runs-on: ubuntu-latest
outputs:
- matrix-0: ${{ steps.set-matrix.outputs.matrix-0 }}
- matrix-1: ${{ steps.set-matrix.outputs.matrix-1 }}
+ python-build-matrix-0: ${{ steps.set-matrix.outputs.python-build-matrix-0 }}
+ python-build-matrix-1: ${{ steps.set-matrix.outputs.python-build-matrix-1 }}
+ docker-build-matrix: ${{ steps.set-matrix.outputs.docker-build-matrix }}
any_builds: ${{ steps.set-matrix.outputs.any_builds }}
pythonbuild_changed: ${{ steps.check-pythonbuild.outputs.changed }}
steps:
@@ -152,13 +148,14 @@ jobs:
--max-shards 2 \
> matrix.json
- echo "matrix-0=$(jq -c '.["0"]' matrix.json)" >> $GITHUB_OUTPUT
- echo "matrix-1=$(jq -c '.["1"]' matrix.json)" >> $GITHUB_OUTPUT
+ echo "python-build-matrix-0=$(jq -c '."python-build"["0"]' matrix.json)" >> $GITHUB_OUTPUT
+ echo "python-build-matrix-1=$(jq -c '."python-build"["1"]' matrix.json)" >> $GITHUB_OUTPUT
+ echo "docker-build-matrix=$(jq -c '."docker-build"' matrix.json)" >> $GITHUB_OUTPUT
# Display the matrix for debugging too
cat matrix.json | jq
- if jq -e '.["0"].include | length > 0' matrix.json > /dev/null; then
+ if jq -e '."python-build"["0"].include | length > 0' matrix.json > /dev/null; then
# Build matrix has entries
echo "any_builds=true" >> $GITHUB_OUTPUT
else
@@ -189,7 +186,7 @@ jobs:
attestations: write
runs-on: ${{ matrix.runner }}
strategy:
- matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix-0) }}
+ matrix: ${{ fromJson(needs.generate-matrix.outputs.python-build-matrix-0) }}
fail-fast: false
name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }}
steps:
@@ -289,7 +286,7 @@ jobs:
attestations: write
runs-on: ${{ matrix.runner }}
strategy:
- matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix-1) }}
+ matrix: ${{ fromJson(needs.generate-matrix.outputs.python-build-matrix-1) }}
fail-fast: false
name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }}
steps:
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index af9a80f..918323d 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -67,11 +67,15 @@ jobs:
- name: Generate build matrix
id: set-matrix
run: |
- uv run ci-matrix.py --platform darwin --labels '${{ steps.get-labels.outputs.labels }}' > matrix.json && echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT
+ uv run ci-matrix.py --platform darwin --labels '${{ steps.get-labels.outputs.labels }}' > matrix.json
+
+ # Extract python-build matrix
+ echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT
+
# Display the matrix for debugging too
cat matrix.json | jq
- if jq -e '.include | length > 0' matrix.json > /dev/null; then
+ if jq -e '."python-build".include | length > 0' matrix.json > /dev/null; then
# Build matrix has entries
echo "any_builds=true" >> $GITHUB_OUTPUT
else
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index ad8bbfe..0e03dba 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -67,11 +67,15 @@ jobs:
- name: Generate build matrix
id: set-matrix
run: |
- uv run ci-matrix.py --platform windows --labels '${{ steps.get-labels.outputs.labels }}' > matrix.json && echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT
+ uv run ci-matrix.py --platform windows --labels '${{ steps.get-labels.outputs.labels }}' > matrix.json
+
+ # Extract python-build matrix
+ echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT
+
# Display the matrix for debugging too
cat matrix.json | jq
- if jq -e '.include | length > 0' matrix.json > /dev/null; then
+ if jq -e '."python-build".include | length > 0' matrix.json > /dev/null; then
# Build matrix has entries
echo "any_builds=true" >> $GITHUB_OUTPUT
else
diff --git a/ci-matrix.py b/ci-matrix.py
index c9bccce..8543a58 100644
--- a/ci-matrix.py
+++ b/ci-matrix.py
@@ -19,6 +19,14 @@
CI_EXTRA_SKIP_LABELS = ["documentation"]
CI_MATRIX_SIZE_LIMIT = 256 # The maximum size of a matrix in GitHub Actions
+# Docker images for building toolchains and dependencies
+DOCKER_BUILD_IMAGES = [
+ {"name": "build", "arch": "x86_64"},
+ {"name": "build.cross", "arch": "x86_64"},
+ {"name": "build.cross-riscv64", "arch": "x86_64"},
+ {"name": "gcc", "arch": "x86_64"},
+]
+
def meets_conditional_version(version: str, min_version: str) -> bool:
return Version(version) >= Version(min_version)
@@ -89,12 +97,36 @@ def should_include_entry(entry: dict[str, str], filters: dict[str, set[str]]) ->
return True
-def generate_matrix_entries(
+def generate_docker_matrix_entries(
+ runners: dict[str, Any],
+ platform_filter: Optional[str] = None,
+) -> list[dict[str, str]]:
+ """Generate matrix entries for docker image builds."""
+ if platform_filter and platform_filter != "linux":
+ return []
+
+ matrix_entries = []
+ for image in DOCKER_BUILD_IMAGES:
+ # Find appropriate runner for Linux platform with the specified architecture
+ runner = find_runner(runners, "linux", image["arch"])
+
+ entry = {
+ "name": image["name"],
+ "arch": image["arch"],
+ "runner": runner,
+ }
+ matrix_entries.append(entry)
+
+ return matrix_entries
+
+
+def generate_python_build_matrix_entries(
config: dict[str, Any],
runners: dict[str, Any],
platform_filter: Optional[str] = None,
label_filters: Optional[dict[str, set[str]]] = None,
) -> list[dict[str, str]]:
+ """Generate matrix entries for python builds."""
matrix_entries = []
for platform, platform_config in config.items():
@@ -102,13 +134,13 @@ def generate_matrix_entries(
continue
for target_triple, target_config in platform_config.items():
- add_matrix_entries_for_config(
+ add_python_build_entries_for_config(
matrix_entries,
target_triple,
target_config,
platform,
runners,
- label_filters.get("directives", set()),
+ label_filters.get("directives", set()) if label_filters else set(),
)
# Apply label filters if present
@@ -144,7 +176,7 @@ def find_runner(runners: dict[str, Any], platform: str, arch: str) -> str:
raise RuntimeError(f"No runner found for platform {platform!r} and arch {arch!r}")
-def add_matrix_entries_for_config(
+def add_python_build_entries_for_config(
matrix_entries: list[dict[str, str]],
target_triple: str,
config: dict[str, Any],
@@ -152,6 +184,7 @@ def add_matrix_entries_for_config(
runners: dict[str, Any],
directives: set[str],
) -> None:
+ """Add python build matrix entries for a specific target configuration."""
python_versions = config["python_versions"]
build_options = config["build_options"]
arch = config["arch"]
@@ -233,6 +266,12 @@ def parse_args() -> argparse.Namespace:
action="store_true",
help="If only free runners should be used.",
)
+ parser.add_argument(
+ "--matrix-type",
+ choices=["python-build", "docker-build", "all"],
+ default="all",
+ help="Which matrix types to generate (default: all)",
+ )
return parser.parse_args()
@@ -254,36 +293,59 @@ def main() -> None:
if runner_config.get("free")
}
- entries = generate_matrix_entries(
- config,
- runners,
- args.platform,
- labels,
- )
-
- if args.max_shards:
- matrix = {}
- shards = (len(entries) // CI_MATRIX_SIZE_LIMIT) + 1
- if shards > args.max_shards:
- print(
- f"error: matrix of size {len(entries)} requires {shards} shards, but the maximum is {args.max_shards}; consider increasing `--max-shards`",
- file=sys.stderr,
- )
- sys.exit(1)
- for shard in range(args.max_shards):
- shard_entries = entries[
- shard * CI_MATRIX_SIZE_LIMIT : (shard + 1) * CI_MATRIX_SIZE_LIMIT
- ]
- matrix[str(shard)] = {"include": shard_entries}
- else:
- if len(entries) > CI_MATRIX_SIZE_LIMIT:
- print(
- f"warning: matrix of size {len(entries)} exceeds limit of {CI_MATRIX_SIZE_LIMIT} but sharding is not enabled; consider setting `--max-shards`",
- file=sys.stderr,
+ result = {}
+
+ # Generate python-build matrix if requested
+ python_entries = []
+ if args.matrix_type in ["python-build", "all"]:
+ python_entries = generate_python_build_matrix_entries(
+ config,
+ runners,
+ args.platform,
+ labels,
+ )
+
+ if args.max_shards:
+ python_build_matrix = {}
+ shards = (len(python_entries) // CI_MATRIX_SIZE_LIMIT) + 1
+ if shards > args.max_shards:
+ print(
+ f"error: python-build matrix of size {len(python_entries)} requires {shards} shards, but the maximum is {args.max_shards}; consider increasing `--max-shards`",
+ file=sys.stderr,
+ )
+ sys.exit(1)
+ for shard in range(args.max_shards):
+ shard_entries = python_entries[
+ shard * CI_MATRIX_SIZE_LIMIT : (shard + 1) * CI_MATRIX_SIZE_LIMIT
+ ]
+ python_build_matrix[str(shard)] = {"include": shard_entries}
+ result["python-build"] = python_build_matrix
+ else:
+ if len(python_entries) > CI_MATRIX_SIZE_LIMIT:
+ print(
+ f"warning: python-build matrix of size {len(python_entries)} exceeds limit of {CI_MATRIX_SIZE_LIMIT} but sharding is not enabled; consider setting `--max-shards`",
+ file=sys.stderr,
+ )
+ result["python-build"] = {"include": python_entries}
+
+ # Generate docker-build matrix if requested
+ # Only include docker builds if there are Linux python builds
+ if args.matrix_type in ["docker-build", "all"]:
+ # Check if we have any Linux python builds
+ has_linux_builds = any(
+ entry.get("platform") == "linux" for entry in python_entries
+ )
+
+ # If no platform filter or explicitly requesting docker-build only, include docker builds
+ # Otherwise, only include if there are Linux python builds
+ if args.matrix_type == "docker-build" or has_linux_builds:
+ docker_entries = generate_docker_matrix_entries(
+ runners,
+ args.platform,
)
- matrix = {"include": entries}
+ result["docker-build"] = {"include": docker_entries}
- print(json.dumps(matrix))
+ print(json.dumps(result))
if __name__ == "__main__":
From 449d3e7a2b03a311884b40ed90f98bfc90bee01e Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Sat, 28 Jun 2025 11:53:04 -0500
Subject: [PATCH 09/72] Generate the matrix for building the `pythonbuild`
crate (#673)
As in #672 this seems helpful for #670
---
.github/workflows/linux.yml | 49 ++++++++--------
.github/workflows/macos.yml | 44 ++++++++-------
.github/workflows/windows.yml | 44 ++++++++-------
ci-matrix.py | 102 +++++++++++++++++++++++++++++-----
4 files changed, 162 insertions(+), 77 deletions(-)
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 6f73a95..8ae87e7 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -13,11 +13,14 @@ env:
FORCE_COLOR: 1
jobs:
- pythonbuild:
- if: ${{ needs.generate-matrix.outputs.pythonbuild_changed == 'true' || needs.generate-matrix.outputs.any_builds == 'true' || github.ref == 'refs/heads/main' }}
+ crate-build:
needs:
- generate-matrix
- runs-on: depot-ubuntu-22.04
+ runs-on: ${{ matrix.runner }}
+ strategy:
+ matrix: ${{ fromJson(needs.generate-matrix.outputs.crate-build-matrix) }}
+ fail-fast: false
+ name: crate / ${{ matrix.arch }}
steps:
- name: Install System Dependencies
run: |
@@ -45,7 +48,7 @@ jobs:
- name: Upload pythonbuild Executable
uses: actions/upload-artifact@v4
with:
- name: pythonbuild
+ name: ${{ matrix.crate_artifact_name }}
path: target/release/pythonbuild
image:
@@ -55,7 +58,7 @@ jobs:
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.docker-build-matrix) }}
- name: ${{ matrix.name }}
+ name: image / ${{ matrix.name }}
runs-on: ${{ matrix.runner }}
permissions:
packages: write
@@ -122,8 +125,8 @@ jobs:
python-build-matrix-0: ${{ steps.set-matrix.outputs.python-build-matrix-0 }}
python-build-matrix-1: ${{ steps.set-matrix.outputs.python-build-matrix-1 }}
docker-build-matrix: ${{ steps.set-matrix.outputs.docker-build-matrix }}
+ crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }}
any_builds: ${{ steps.set-matrix.outputs.any_builds }}
- pythonbuild_changed: ${{ steps.check-pythonbuild.outputs.changed }}
steps:
- uses: actions/checkout@v4
with:
@@ -139,6 +142,18 @@ jobs:
LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")')
echo "labels=$LABELS" >> $GITHUB_OUTPUT
+ - name: Check if the `pythonbuild` crate changed
+ id: check-pythonbuild
+ env:
+ BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }}
+ run: |
+ merge_base=$(git merge-base HEAD "origin/${BASE_REF}")
+ if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then
+ echo "changed=false" >> "$GITHUB_OUTPUT"
+ else
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+ fi
+
- name: Generate build matrix
id: set-matrix
run: |
@@ -146,11 +161,13 @@ jobs:
--platform linux \
--labels '${{ steps.get-labels.outputs.labels }}' \
--max-shards 2 \
+ ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} \
> matrix.json
echo "python-build-matrix-0=$(jq -c '."python-build"["0"]' matrix.json)" >> $GITHUB_OUTPUT
echo "python-build-matrix-1=$(jq -c '."python-build"["1"]' matrix.json)" >> $GITHUB_OUTPUT
echo "docker-build-matrix=$(jq -c '."docker-build"' matrix.json)" >> $GITHUB_OUTPUT
+ echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT
# Display the matrix for debugging too
cat matrix.json | jq
@@ -163,22 +180,10 @@ jobs:
echo "any_builds=false" >> $GITHUB_OUTPUT
fi
- - name: Check if the `pythonbuild` crate changed
- id: check-pythonbuild
- env:
- BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }}
- run: |
- merge_base=$(git merge-base HEAD "origin/${BASE_REF}")
- if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then
- echo "changed=false" >> "$GITHUB_OUTPUT"
- else
- echo "changed=true" >> "$GITHUB_OUTPUT"
- fi
-
build-0:
needs:
- generate-matrix
- - pythonbuild
+ - crate-build
- image
# Permissions used for actions/attest-build-provenance
permissions:
@@ -202,7 +207,7 @@ jobs:
- name: Download pythonbuild
uses: actions/download-artifact@v4
with:
- name: pythonbuild
+ name: ${{ matrix.crate_artifact_name }}
path: build
- name: Download images
@@ -278,7 +283,7 @@ jobs:
build-1:
needs:
- generate-matrix
- - pythonbuild
+ - crate-build
- image
# Permissions used for actions/attest-build-provenance
permissions:
@@ -302,7 +307,7 @@ jobs:
- name: Download pythonbuild
uses: actions/download-artifact@v4
with:
- name: pythonbuild
+ name: ${{ matrix.crate_artifact_name }}
path: build
- name: Download images
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 918323d..1199b39 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -13,11 +13,14 @@ env:
FORCE_COLOR: 1
jobs:
- pythonbuild:
- if: ${{ needs.generate-matrix.outputs.pythonbuild_changed == 'true' || needs.generate-matrix.outputs.any_builds == 'true' || github.ref == 'refs/heads/main' }}
+ crate-build:
needs:
- generate-matrix
- runs-on: depot-macos-latest
+ runs-on: ${{ matrix.runner }}
+ strategy:
+ matrix: ${{ fromJson(needs.generate-matrix.outputs.crate-build-matrix) }}
+ fail-fast: false
+ name: crate / ${{ matrix.arch }}
steps:
- uses: actions/checkout@v4
@@ -40,15 +43,15 @@ jobs:
- name: Upload pythonbuild Executable
uses: actions/upload-artifact@v4
with:
- name: pythonbuild
+ name: ${{ matrix.crate_artifact_name }}
path: target/release/pythonbuild
generate-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
+ crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }}
any_builds: ${{ steps.set-matrix.outputs.any_builds }}
- pythonbuild_changed: ${{ steps.check-pythonbuild.outputs.changed }}
steps:
- uses: actions/checkout@v4
with:
@@ -64,13 +67,26 @@ jobs:
LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")')
echo "labels=$LABELS" >> $GITHUB_OUTPUT
+ - name: Check if the `pythonbuild` crate changed
+ id: check-pythonbuild
+ env:
+ BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }}
+ run: |
+ merge_base=$(git merge-base HEAD "origin/${BASE_REF}")
+ if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then
+ echo "changed=false" >> "$GITHUB_OUTPUT"
+ else
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+ fi
+
- name: Generate build matrix
id: set-matrix
run: |
- uv run ci-matrix.py --platform darwin --labels '${{ steps.get-labels.outputs.labels }}' > matrix.json
+ uv run ci-matrix.py --platform darwin --labels '${{ steps.get-labels.outputs.labels }}' ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json
# Extract python-build matrix
echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT
+ echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT
# Display the matrix for debugging too
cat matrix.json | jq
@@ -83,22 +99,10 @@ jobs:
echo "any_builds=false" >> $GITHUB_OUTPUT
fi
- - name: Check if the `pythonbuild` crate changed
- id: check-pythonbuild
- env:
- BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }}
- run: |
- merge_base=$(git merge-base HEAD "origin/${BASE_REF}")
- if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then
- echo "changed=false" >> "$GITHUB_OUTPUT"
- else
- echo "changed=true" >> "$GITHUB_OUTPUT"
- fi
-
build:
needs:
- generate-matrix
- - pythonbuild
+ - crate-build
# Permissions used for actions/attest-build-provenance
permissions:
id-token: write
@@ -121,7 +125,7 @@ jobs:
- name: Download pythonbuild
uses: actions/download-artifact@v4
with:
- name: pythonbuild
+ name: ${{ matrix.crate_artifact_name }}
path: build
- name: Build
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 0e03dba..e285fac 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -13,11 +13,14 @@ env:
FORCE_COLOR: 1
jobs:
- pythonbuild:
- if: ${{ needs.generate-matrix.outputs.pythonbuild_changed == 'true' || needs.generate-matrix.outputs.any_builds == 'true' || github.ref == 'refs/heads/main' }}
+ crate-build:
needs:
- generate-matrix
- runs-on: 'windows-2022'
+ runs-on: ${{ matrix.runner }}
+ strategy:
+ matrix: ${{ fromJson(needs.generate-matrix.outputs.crate-build-matrix) }}
+ fail-fast: false
+ name: crate / ${{ matrix.arch }}
steps:
- uses: actions/checkout@v4
@@ -40,15 +43,15 @@ jobs:
- name: Upload executable
uses: actions/upload-artifact@v4
with:
- name: pythonbuild
+ name: ${{ matrix.crate_artifact_name }}
path: target/release/pythonbuild.exe
generate-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
+ crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }}
any_builds: ${{ steps.set-matrix.outputs.any_builds }}
- pythonbuild_changed: ${{ steps.check-pythonbuild.outputs.changed }}
steps:
- uses: actions/checkout@v4
with:
@@ -64,13 +67,26 @@ jobs:
LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")')
echo "labels=$LABELS" >> $GITHUB_OUTPUT
+ - name: Check if the `pythonbuild` crate changed
+ id: check-pythonbuild
+ env:
+ BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }}
+ run: |
+ merge_base=$(git merge-base HEAD "origin/${BASE_REF}")
+ if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then
+ echo "changed=false" >> "$GITHUB_OUTPUT"
+ else
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+ fi
+
- name: Generate build matrix
id: set-matrix
run: |
- uv run ci-matrix.py --platform windows --labels '${{ steps.get-labels.outputs.labels }}' > matrix.json
+ uv run ci-matrix.py --platform windows --labels '${{ steps.get-labels.outputs.labels }}' ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json
# Extract python-build matrix
echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT
+ echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT
# Display the matrix for debugging too
cat matrix.json | jq
@@ -83,23 +99,11 @@ jobs:
echo "any_builds=false" >> $GITHUB_OUTPUT
fi
- - name: Check if the `pythonbuild` crate changed
- id: check-pythonbuild
- env:
- BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }}
- run: |
- merge_base=$(git merge-base HEAD "origin/${BASE_REF}")
- if git diff --quiet "${merge_base}...HEAD" -- ':src/*.rs'; then
- echo "changed=false" >> "$GITHUB_OUTPUT"
- else
- echo "changed=true" >> "$GITHUB_OUTPUT"
- fi
-
build:
timeout-minutes: 60
needs:
- generate-matrix
- - pythonbuild
+ - crate-build
# Permissions used for actions/attest-build-provenance
permissions:
id-token: write
@@ -127,7 +131,7 @@ jobs:
- name: Download pythonbuild Executable
uses: actions/download-artifact@v4
with:
- name: pythonbuild
+ name: ${{ matrix.crate_artifact_name }}
# We need to do this before we activate the VC++ environment or else binary packages
# don't get compiled properly.
diff --git a/ci-matrix.py b/ci-matrix.py
index 8543a58..96059a9 100644
--- a/ci-matrix.py
+++ b/ci-matrix.py
@@ -19,6 +19,7 @@
CI_EXTRA_SKIP_LABELS = ["documentation"]
CI_MATRIX_SIZE_LIMIT = 256 # The maximum size of a matrix in GitHub Actions
+
# Docker images for building toolchains and dependencies
DOCKER_BUILD_IMAGES = [
{"name": "build", "arch": "x86_64"},
@@ -28,6 +29,10 @@
]
+def crate_artifact_name(platform: str, arch: str) -> str:
+ return f"crate-{platform}-{arch}"
+
+
def meets_conditional_version(version: str, min_version: str) -> bool:
return Version(version) >= Version(min_version)
@@ -108,7 +113,7 @@ def generate_docker_matrix_entries(
matrix_entries = []
for image in DOCKER_BUILD_IMAGES:
# Find appropriate runner for Linux platform with the specified architecture
- runner = find_runner(runners, "linux", image["arch"])
+ runner = find_runner(runners, "linux", image["arch"], False)
entry = {
"name": image["name"],
@@ -120,6 +125,51 @@ def generate_docker_matrix_entries(
return matrix_entries
+def generate_crate_build_matrix_entries(
+ python_entries: list[dict[str, str]],
+ runners: dict[str, Any],
+ config: dict[str, Any],
+ force_crate_build: bool = False,
+ platform_filter: Optional[str] = None,
+) -> list[dict[str, str]]:
+ """Generate matrix entries for crate builds based on python build matrix."""
+ needed_builds = set()
+ for entry in python_entries:
+ # The crate build will need to match the runner's architecture
+ runner = runners[entry["runner"]]
+ needed_builds.add((entry["platform"], runner["arch"]))
+
+ # If forcing crate build, also include all possible native builds
+ if force_crate_build:
+ for platform, platform_config in config.items():
+ # Filter by platform if specified
+ if platform_filter and platform != platform_filter:
+ continue
+
+ for target_config in platform_config.values():
+ # Only include if native (run: true means native)
+ if not target_config.get("run"):
+ continue
+
+ arch = target_config["arch"]
+ needed_builds.add((platform, arch))
+
+ # Create matrix entries for each needed build
+ return [
+ {
+ "platform": platform,
+ "arch": arch,
+ "runner": find_runner(runners, platform, arch, True),
+ "crate_artifact_name": crate_artifact_name(
+ platform,
+ arch,
+ ),
+ }
+ for platform, arch in needed_builds
+ if not platform_filter or platform == platform_filter
+ ]
+
+
def generate_python_build_matrix_entries(
config: dict[str, Any],
runners: dict[str, Any],
@@ -154,10 +204,12 @@ def generate_python_build_matrix_entries(
return matrix_entries
-def find_runner(runners: dict[str, Any], platform: str, arch: str) -> str:
+def find_runner(runners: dict[str, Any], platform: str, arch: str, free: bool) -> str:
# Find a matching platform first
match_platform = [
- runner for runner in runners if runners[runner]["platform"] == platform
+ runner
+ for runner in runners
+ if runners[runner]["platform"] == platform and runners[runner]["free"] == free
]
# Then, find a matching architecture
@@ -173,7 +225,9 @@ def find_runner(runners: dict[str, Any], platform: str, arch: str) -> str:
if match_platform:
return match_platform[0]
- raise RuntimeError(f"No runner found for platform {platform!r} and arch {arch!r}")
+ raise RuntimeError(
+ f"No runner found for platform {platform!r} and arch {arch!r} with free={free}"
+ )
def add_python_build_entries_for_config(
@@ -188,7 +242,7 @@ def add_python_build_entries_for_config(
python_versions = config["python_versions"]
build_options = config["build_options"]
arch = config["arch"]
- runner = find_runner(runners, platform, arch)
+ runner = find_runner(runners, platform, arch, False)
# Create base entry that will be used for all variants
base_entry = {
@@ -199,6 +253,8 @@ def add_python_build_entries_for_config(
# If `run` is in the config, use that — otherwise, default to if the
# runner architecture matches the build architecture
"run": str(config.get("run", runners[runner]["arch"] == arch)).lower(),
+ # Use the crate artifact built for the runner's architecture
+ "crate_artifact_name": crate_artifact_name(platform, runners[runner]["arch"]),
}
# Add optional fields if they exist
@@ -266,9 +322,14 @@ def parse_args() -> argparse.Namespace:
action="store_true",
help="If only free runners should be used.",
)
+ parser.add_argument(
+ "--force-crate-build",
+ action="store_true",
+ help="Force crate builds to be included even without python builds.",
+ )
parser.add_argument(
"--matrix-type",
- choices=["python-build", "docker-build", "all"],
+ choices=["python-build", "docker-build", "crate-build", "all"],
default="all",
help="Which matrix types to generate (default: all)",
)
@@ -295,16 +356,16 @@ def main() -> None:
result = {}
- # Generate python-build matrix if requested
- python_entries = []
- if args.matrix_type in ["python-build", "all"]:
- python_entries = generate_python_build_matrix_entries(
- config,
- runners,
- args.platform,
- labels,
- )
+ # Generate python build entries
+ python_entries = generate_python_build_matrix_entries(
+ config,
+ runners,
+ args.platform,
+ labels,
+ )
+ # Output python-build matrix if requested
+ if args.matrix_type in ["python-build", "all"]:
if args.max_shards:
python_build_matrix = {}
shards = (len(python_entries) // CI_MATRIX_SIZE_LIMIT) + 1
@@ -345,6 +406,17 @@ def main() -> None:
)
result["docker-build"] = {"include": docker_entries}
+ # Generate crate-build matrix if requested
+ if args.matrix_type in ["crate-build", "all"]:
+ crate_entries = generate_crate_build_matrix_entries(
+ python_entries,
+ runners,
+ config,
+ args.force_crate_build,
+ args.platform,
+ )
+ result["crate-build"] = {"include": crate_entries}
+
print(json.dumps(result))
From e17faa9e098156baeeca3ae0c2249c460fa37bb2 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Sat, 28 Jun 2025 14:04:24 -0500
Subject: [PATCH 10/72] Update the crate build runner logic (#674)
Using the free GitHub runners for Linux breaks those builds :)
---
ci-matrix.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/ci-matrix.py b/ci-matrix.py
index 96059a9..cfccdd5 100644
--- a/ci-matrix.py
+++ b/ci-matrix.py
@@ -159,7 +159,13 @@ def generate_crate_build_matrix_entries(
{
"platform": platform,
"arch": arch,
- "runner": find_runner(runners, platform, arch, True),
+ # Use the GitHub runner for Windows, because the Depot one is
+ # missing a Rust toolchain. On Linux, it's important that the the
+ # `python-build` runner matches the `crate-build` runner because of
+ # GLIBC version mismatches.
+ "runner": find_runner(
+ runners, platform, arch, True if platform == "windows" else False
+ ),
"crate_artifact_name": crate_artifact_name(
platform,
arch,
From b233563209eb92c9e93d284418ee8d7eefcef4a7 Mon Sep 17 00:00:00 2001
From: Dustin Rodrigues
Date: Sun, 29 Jun 2025 11:59:01 -0400
Subject: [PATCH 11/72] use raw string literal for regex (#675)
Uses a raw string literal for the regex to avoid
```
python-build-standalone/pythonbuild/cpython.py:675: SyntaxWarning: invalid escape sequence '\{'
RE_INITTAB_ENTRY = re.compile('\{"([^"]+)", ([^\}]+)\},')
```
---
pythonbuild/cpython.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pythonbuild/cpython.py b/pythonbuild/cpython.py
index f339037..c52f7ce 100644
--- a/pythonbuild/cpython.py
+++ b/pythonbuild/cpython.py
@@ -672,7 +672,7 @@ def derive_setup_local(
}
-RE_INITTAB_ENTRY = re.compile('\{"([^"]+)", ([^\}]+)\},')
+RE_INITTAB_ENTRY = re.compile(r'\{"([^"]+)", ([^\}]+)\},')
def parse_config_c(s: str):
From 14f33e81921e8f2bf20a8e58212a8f81eed2f1ba Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Mon, 30 Jun 2025 15:43:24 -0500
Subject: [PATCH 12/72] Include aarch64 Window artifacts in releases (#679)
---
src/release.rs | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/release.rs b/src/release.rs
index 60e46c9..d4f890e 100644
--- a/src/release.rs
+++ b/src/release.rs
@@ -129,6 +129,18 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy::
}],
},
);
+ h.insert(
+ "aarch64-pc-windows-msvc",
+ TripleRelease {
+ suffixes: vec!["pgo"],
+ install_only_suffix: "pgo",
+ python_version_requirement: Some(VersionSpecifier::from_str(">=3.11").unwrap()),
+ conditional_suffixes: vec![ConditionalSuffixes {
+ python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
+ suffixes: vec!["freethreaded+pgo"],
+ }],
+ },
+ );
// Linux.
let linux_suffixes_pgo = vec!["debug", "pgo+lto"];
From c646c36b062051ebf5d211dc86763e5bd72599e2 Mon Sep 17 00:00:00 2001
From: Gregory Szorc
Date: Fri, 16 May 2025 19:13:29 -0700
Subject: [PATCH 13/72] xtrans 1.5.0 -> 1.6.0
This seems to "just work." Let's stay modern.
---
pythonbuild/downloads.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index 3e7adc8..0367faa 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -392,10 +392,10 @@
"version": "2019.1",
},
"xtrans": {
- "url": "https://www.x.org/archive/individual/lib/xtrans-1.5.0.tar.gz",
- "size": 230197,
- "sha256": "a806f8a92f879dcd0146f3f1153fdffe845f2fc0df9b1a26c19312b7b0a29c86",
- "version": "1.5.0",
+ "url": "https://www.x.org/archive/individual/lib/xtrans-1.6.0.tar.gz",
+ "size": 239113,
+ "sha256": "936b74c60b19c317c3f3cb1b114575032528dbdaf428740483200ea874c2ca0a",
+ "version": "1.6.0",
},
# IMPORTANT: xz 5.6 has a backdoor. Be extremely cautious before taking any xz
# upgrade since it isn't clear which versions are safe.
From dd0b436c269fc10f7b2781b699387d3f19bdd645 Mon Sep 17 00:00:00 2001
From: Gregory Szorc
Date: Fri, 16 May 2025 19:14:46 -0700
Subject: [PATCH 14/72] x11-util-macros 1.20.1 -> 1.20.2
---
pythonbuild/downloads.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index 0367faa..3d888e8 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -372,10 +372,10 @@
"license_file": "LICENSE.libuuid.txt",
},
"x11-util-macros": {
- "url": "https://www.x.org/archive/individual/util/util-macros-1.20.1.tar.gz",
- "size": 105481,
- "sha256": "b373f72887b1394ce2193180a60cb0d1fb8b17bc96ddd770cfd7a808cb489a15",
- "version": "1.20.1",
+ "url": "https://www.x.org/archive/individual/util/util-macros-1.20.2.tar.gz",
+ "size": 105410,
+ "sha256": "f642f8964d81acdf06653fdf9dbc210c43ce4bd308bd644a8d573148d0ced76b",
+ "version": "1.20.2",
},
"xcb-proto": {
"url": "https://xcb.freedesktop.org/dist/xcb-proto-1.17.0.tar.xz",
From d8ef90ad326e0e8b7074ba097df5a414288ff3c6 Mon Sep 17 00:00:00 2001
From: Gregory Szorc
Date: Fri, 16 May 2025 19:18:59 -0700
Subject: [PATCH 15/72] xorgproto 2019.1 -> 2024.1
I think deletion of the legacy proto packages a few commits ago fixed up
the build failures the deleted comment alluded to.
---
pythonbuild/downloads.py | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index 3d888e8..c1cae14 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -383,13 +383,11 @@
"sha256": "2c1bacd2110f4799f74de6ebb714b94cf6f80fb112316b1219480fd22562148c",
"version": "1.17.0",
},
- # Newer versions from at least 2023 have build failures for reasons we haven't
- # fully investigated.
"xorgproto": {
- "url": "https://www.x.org/archive/individual/proto/xorgproto-2019.1.tar.gz",
- "size": 1119813,
- "sha256": "38ad1d8316515785d53c5162b4b7022918e03c11d72a5bd9df0a176607f42bca",
- "version": "2019.1",
+ "url": "https://www.x.org/archive/individual/proto/xorgproto-2024.1.tar.gz",
+ "size": 1115486,
+ "sha256": "4f6b9b4faf91e5df8265b71843a91fc73dc895be6210c84117a996545df296ce",
+ "version": "2024.1",
},
"xtrans": {
"url": "https://www.x.org/archive/individual/lib/xtrans-1.6.0.tar.gz",
From 21cf744dda2d0e19329950a81a07d9067179f976 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Sat, 28 Jun 2025 14:04:53 -0500
Subject: [PATCH 16/72] Enable native builds on Linux aarch64
I just published an LLVM 20 toolchain for aarch64. The toolchain
has support for PGO and BOLT.
This commit switches the Linux aarch64 builds to be performed natively
on aarch64 machines. PGO and BOLT are enabled on the builds, hopefully
making them a bit faster.
---
.github/workflows/linux.yml | 18 +++----
ci-matrix.py | 2 +
ci-runners.yaml | 9 ++--
ci-targets.yaml | 6 +--
cpython-unix/Makefile | 12 ++---
cpython-unix/base.debian9.Dockerfile | 38 ++++++++++++++
cpython-unix/build-binutils.sh | 8 ++-
cpython-unix/build-main.py | 1 +
cpython-unix/build.debian9.Dockerfile | 16 ++++++
cpython-unix/build.py | 74 +++++++++++++++++----------
cpython-unix/gcc.debian9.Dockerfile | 14 +++++
cpython-unix/targets.yml | 21 ++++++--
pythonbuild/docker.py | 17 ++++--
pythonbuild/downloads.py | 7 +++
pythonbuild/utils.py | 14 +++++
15 files changed, 195 insertions(+), 62 deletions(-)
create mode 100644 cpython-unix/base.debian9.Dockerfile
create mode 100644 cpython-unix/build.debian9.Dockerfile
create mode 100644 cpython-unix/gcc.debian9.Dockerfile
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 8ae87e7..d4602fb 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -2,7 +2,7 @@ name: linux
on:
push:
- branches: [main]
+ branches: [ main ]
pull_request:
concurrency:
@@ -58,7 +58,7 @@ jobs:
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.docker-build-matrix) }}
- name: image / ${{ matrix.name }}
+ name: image / ${{ matrix.arch }} / ${{ matrix.name }}
runs-on: ${{ matrix.runner }}
permissions:
packages: write
@@ -100,23 +100,23 @@ jobs:
# Cache from the default branch of the canonical repo so forks can have cache hits.
# Ignore errors on cache writes so CI of forks works without a valid GHCR config.
cache-from: |
- type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-${{ env.GIT_REF_NAME }}
- type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-main
- type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.name }}-main
+ type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-${{ env.GIT_REF_NAME }}
+ type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-main
+ type=registry,ref=ghcr.io/astral-sh/python-build-standalone:${{ matrix.name }}-linux_${{ matrix.arch }}-main
cache-to: |
- type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-${{ env.GIT_REF_NAME }},ignore-error=true
+ type=registry,ref=ghcr.io/${{ env.REPO_NAME }}:${{ matrix.name }}-linux_${{ matrix.arch }}-${{ env.GIT_REF_NAME }},ignore-error=true
outputs: |
- type=docker,dest=build/image-${{ matrix.name }}.tar
+ type=docker,dest=build/image-${{ matrix.name }}.linux_${{ matrix.arch }}.tar
- name: Compress Image
run: |
- echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.name }}
+ echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.name }}.linux_${{ matrix.arch }}
zstd -v -T0 -6 --rm build/image-*.tar
- name: Upload Docker Image
uses: actions/upload-artifact@v4
with:
- name: image-${{ matrix.name }}
+ name: image-${{ matrix.name }}-linux_${{ matrix.arch }}
path: build/image-*
generate-matrix:
diff --git a/ci-matrix.py b/ci-matrix.py
index cfccdd5..91cfa95 100644
--- a/ci-matrix.py
+++ b/ci-matrix.py
@@ -25,7 +25,9 @@
{"name": "build", "arch": "x86_64"},
{"name": "build.cross", "arch": "x86_64"},
{"name": "build.cross-riscv64", "arch": "x86_64"},
+ {"name": "build.debian9", "arch": "aarch64"},
{"name": "gcc", "arch": "x86_64"},
+ {"name": "gcc.debian9", "arch": "aarch64"},
]
diff --git a/ci-runners.yaml b/ci-runners.yaml
index 43ff941..dae6aab 100644
--- a/ci-runners.yaml
+++ b/ci-runners.yaml
@@ -5,11 +5,10 @@ depot-ubuntu-22.04:
platform: linux
free: false
-# TODO: Enable this runner to perform native builds for aarch64
-# depot-ubuntu-22.04-arm:
-# arch: aarch64
-# platform: linux
-# free: false
+depot-ubuntu-22.04-arm:
+ arch: aarch64
+ platform: linux
+ free: false
depot-macos-latest:
arch: x86_64
diff --git a/ci-targets.yaml b/ci-targets.yaml
index c7b4bd1..c59d5b7 100644
--- a/ci-targets.yaml
+++ b/ci-targets.yaml
@@ -50,13 +50,11 @@ linux:
- "3.14"
build_options:
- debug
- - noopt
- - lto
+ - pgo+lto
build_options_conditional:
- options:
- freethreaded+debug
- - freethreaded+noopt
- - freethreaded+lto
+ - freethreaded+pgo+lto
minimum-python-version: "3.13"
armv7-unknown-linux-gnueabi:
diff --git a/cpython-unix/Makefile b/cpython-unix/Makefile
index 4cacaff..6e4b007 100644
--- a/cpython-unix/Makefile
+++ b/cpython-unix/Makefile
@@ -66,7 +66,7 @@ TOOLCHAIN_DEPENDS := \
PYTHON_DEP_DEPENDS := \
$(OUTDIR)/targets/$(TARGET_TRIPLE) \
- $(if $(PYBUILD_NO_DOCKER),,$(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).tar) \
+ $(if $(PYBUILD_NO_DOCKER),,$(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).$(HOST_PLATFORM).tar) \
$(TOOLCHAIN_DEPENDS) \
$(NULL)
@@ -75,18 +75,18 @@ HOST_PYTHON_DEPENDS := $(OUTDIR)/cpython-$(PYTHON_MAJOR_VERSION)-$(CPYTHON_$(PYT
default: $(OUTDIR)/cpython-$(CPYTHON_$(PYTHON_MAJOR_VERSION)_VERSION)-$(PACKAGE_SUFFIX).tar
ifndef PYBUILD_NO_DOCKER
-$(OUTDIR)/image-%.tar: $(OUTDIR)/%.Dockerfile
+$(OUTDIR)/image-%.$(HOST_PLATFORM).tar: $(OUTDIR)/%.Dockerfile
$(RUN_BUILD) --toolchain image-$*
endif
-$(OUTDIR)/binutils-$(BINUTILS_VERSION)-$(HOST_PLATFORM).tar: $(OUTDIR)/image-gcc.tar $(HERE)/build-binutils.sh
- $(RUN_BUILD) --toolchain binutils
+$(OUTDIR)/binutils-$(BINUTILS_VERSION)-$(HOST_PLATFORM).tar: $(HERE)/build-binutils.sh
+ $(RUN_BUILD) --toolchain --docker-image $(DOCKER_IMAGE_GCC) binutils
$(OUTDIR)/$(CLANG_FILENAME):
$(RUN_BUILD) --toolchain clang --target-triple $(TARGET_TRIPLE)
$(OUTDIR)/musl-$(MUSL_VERSION)-$(HOST_PLATFORM).tar: $(BASE_TOOLCHAIN_DEPENDS) $(HERE)/build-musl.sh
- $(RUN_BUILD) --toolchain musl
+ $(RUN_BUILD) --toolchain musl --docker-image $(DOCKER_IMAGE_GCC)
ifeq ($(HOST_PLATFORM),linux_x86_64)
TOOLCHAIN_TARGET := $(OUTDIR)/musl-$(MUSL_VERSION)-$(HOST_PLATFORM).tar
@@ -125,7 +125,7 @@ $(OUTDIR)/libffi-3.3-$(LIBFFI_3.3_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_D
$(OUTDIR)/libffi-$(LIBFFI_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libffi.sh
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libffi
-$(OUTDIR)/libpthread-stubs-$(LIBPTHREAD_STUBS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libpthread-stubs.sh $(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).tar
+$(OUTDIR)/libpthread-stubs-$(LIBPTHREAD_STUBS_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-libpthread-stubs.sh $(OUTDIR)/image-$(DOCKER_IMAGE_BUILD).$(HOST_PLATFORM).tar
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) libpthread-stubs
LIBX11_DEPENDS = \
diff --git a/cpython-unix/base.debian9.Dockerfile b/cpython-unix/base.debian9.Dockerfile
new file mode 100644
index 0000000..1b47b35
--- /dev/null
+++ b/cpython-unix/base.debian9.Dockerfile
@@ -0,0 +1,38 @@
+# Debian Stretch.
+FROM debian@sha256:c5c5200ff1e9c73ffbf188b4a67eb1c91531b644856b4aefe86a58d2f0cb05be
+MAINTAINER Gregory Szorc
+
+RUN groupadd -g 1000 build && \
+ useradd -u 1000 -g 1000 -d /build -s /bin/bash -m build && \
+ mkdir /tools && \
+ chown -R build:build /build /tools
+
+ENV HOME=/build \
+ SHELL=/bin/bash \
+ USER=build \
+ LOGNAME=build \
+ HOSTNAME=builder \
+ DEBIAN_FRONTEND=noninteractive
+
+CMD ["/bin/bash", "--login"]
+WORKDIR '/build'
+
+RUN for s in debian_stretch debian_stretch-updates debian-security_stretch/updates; do \
+ echo "deb http://snapshot.debian.org/archive/${s%_*}/20230423T032736Z/ ${s#*_} main"; \
+ done > /etc/apt/sources.list && \
+ ( echo 'quiet "true";'; \
+ echo 'APT::Get::Assume-Yes "true";'; \
+ echo 'APT::Install-Recommends "false";'; \
+ echo 'Acquire::Check-Valid-Until "false";'; \
+ echo 'Acquire::Retries "5";'; \
+ ) > /etc/apt/apt.conf.d/99cpython-portable
+
+# apt iterates all available file descriptors up to rlim_max and calls
+# fcntl(fd, F_SETFD, FD_CLOEXEC). This can result in millions of system calls
+# (we've seen 1B in the wild) and cause operations to take seconds to minutes.
+# Setting a fd limit mitigates.
+#
+# Attempts at enforcing the limit globally via /etc/security/limits.conf and
+# /root/.bashrc were not successful. Possibly because container image builds
+# don't perform a login or use a shell the way we expect.
+RUN ulimit -n 10000 && apt-get update
diff --git a/cpython-unix/build-binutils.sh b/cpython-unix/build-binutils.sh
index c52e823..2bb8936 100755
--- a/cpython-unix/build-binutils.sh
+++ b/cpython-unix/build-binutils.sh
@@ -11,9 +11,15 @@ tar -xf binutils-${BINUTILS_VERSION}.tar.xz
mkdir binutils-objdir
pushd binutils-objdir
+if [ "$(uname -m)" = "x86_64" ]; then
+ triple="x86_64-unknown-linux-gnu"
+else
+ triple="aarch64-unknown-linux-gnu"
+fi
+
# gprofng requires a bison newer than what we have. So just disable it.
../binutils-${BINUTILS_VERSION}/configure \
- --build=x86_64-unknown-linux-gnu \
+ --build=${triple} \
--prefix=/tools/host \
--enable-plugins \
--enable-gprofng=no \
diff --git a/cpython-unix/build-main.py b/cpython-unix/build-main.py
index a353daf..7a7d08b 100755
--- a/cpython-unix/build-main.py
+++ b/cpython-unix/build-main.py
@@ -95,6 +95,7 @@ def main():
"toolchain-image-build",
"toolchain-image-build.cross",
"toolchain-image-build.cross-riscv64",
+ "toolchain-image-build.debian9",
"toolchain-image-gcc",
"toolchain-image-xcb",
"toolchain-image-xcb.cross",
diff --git a/cpython-unix/build.debian9.Dockerfile b/cpython-unix/build.debian9.Dockerfile
new file mode 100644
index 0000000..1f7c91b
--- /dev/null
+++ b/cpython-unix/build.debian9.Dockerfile
@@ -0,0 +1,16 @@
+{% include 'base.debian9.Dockerfile' %}
+
+RUN ulimit -n 10000 && apt-get install \
+ bzip2 \
+ file \
+ libc6-dev \
+ libffi-dev \
+ make \
+ patch \
+ perl \
+ pkg-config \
+ tar \
+ xz-utils \
+ unzip \
+ zip \
+ zlib1g-dev
diff --git a/cpython-unix/build.py b/cpython-unix/build.py
index 6f98e99..01d39b2 100755
--- a/cpython-unix/build.py
+++ b/cpython-unix/build.py
@@ -88,14 +88,21 @@ def add_target_env(env, build_platform, target_triple, build_env):
extra_host_cflags = []
extra_host_ldflags = []
- if build_platform == "linux_x86_64":
- env["BUILD_TRIPLE"] = "x86_64-unknown-linux-gnu"
+ if build_platform.startswith("linux_"):
+ machine = platform.machine()
- env["TARGET_TRIPLE"] = (
- target_triple.replace("x86_64_v2-", "x86_64-")
- .replace("x86_64_v3-", "x86_64-")
- .replace("x86_64_v4-", "x86_64-")
- )
+ if machine == "aarch64":
+ env["BUILD_TRIPLE"] = "aarch64-unknown-linux-gnu"
+ env["TARGET_TRIPLE"] = target_triple
+ elif machine == "x86_64":
+ env["BUILD_TRIPLE"] = "x86_64-unknown-linux-gnu"
+ env["TARGET_TRIPLE"] = (
+ target_triple.replace("x86_64_v2-", "x86_64-")
+ .replace("x86_64_v3-", "x86_64-")
+ .replace("x86_64_v4-", "x86_64-")
+ )
+ else:
+ raise Exception("unhandled Linux machine value: %s" % machine)
# This will make x86_64_v2, etc count as cross-compiling. This is
# semantically correct, since the current machine may not support
@@ -105,7 +112,7 @@ def add_target_env(env, build_platform, target_triple, build_env):
):
env["CROSS_COMPILING"] = "1"
- if build_platform.startswith("macos_"):
+ elif build_platform.startswith("macos_"):
machine = platform.machine()
if machine == "arm64":
@@ -188,6 +195,8 @@ def add_target_env(env, build_platform, target_triple, build_env):
extra_host_cflags.extend(["-isysroot", host_sdk_path])
extra_host_ldflags.extend(["-isysroot", host_sdk_path])
+ else:
+ raise Exception("unhandled build platform: %s" % build_platform)
env["EXTRA_HOST_CFLAGS"] = " ".join(extra_host_cflags)
env["EXTRA_HOST_LDFLAGS"] = " ".join(extra_host_ldflags)
@@ -496,10 +505,14 @@ def python_build_info(
binary_suffix = ""
- if platform == "linux_x86_64":
+ if platform in ("linux_x86_64", "linux_aarch64"):
+ arch = platform.removeprefix("linux_")
+
bi["core"]["static_lib"] = (
- "install/lib/python{version}/config-{version}{binary_suffix}-x86_64-linux-gnu/libpython{version}{binary_suffix}.a".format(
- version=version, binary_suffix=binary_suffix
+ "install/lib/python{version}/config-{version}{binary_suffix}-{arch}-linux-gnu/libpython{version}{binary_suffix}.a".format(
+ version=version,
+ binary_suffix=binary_suffix,
+ arch=arch,
)
)
@@ -579,7 +592,10 @@ def python_build_info(
if lib.startswith("-l"):
lib = lib[2:]
- if platform == "linux_x86_64" and lib not in linux_allowed_system_libraries:
+ if (
+ platform in ("linux_x86_64", "linux_aarch64")
+ and lib not in linux_allowed_system_libraries
+ ):
raise Exception("unexpected library in LIBS (%s): %s" % (libs, lib))
elif (
platform.startswith("macos_")
@@ -851,7 +867,7 @@ def build_cpython(
extension_module_loading = ["builtin"]
crt_features = []
- if host_platform == "linux_x86_64":
+ if host_platform in ("linux_x86_64", "linux_aarch64"):
if "static" in parsed_build_options:
crt_features.append("static")
else:
@@ -1080,10 +1096,14 @@ def main():
with image_path.open("rb") as fh:
image_data = fh.read()
- build_docker_image(client, image_data, BUILD, image_name)
+ build_docker_image(client, image_data, BUILD, image_name, host_platform)
elif action == "binutils":
- build_binutils(client, get_image(client, ROOT, BUILD, "gcc"), host_platform)
+ build_binutils(
+ client,
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
+ host_platform,
+ )
elif action == "clang":
materialize_clang(host_platform, target_triple)
@@ -1091,7 +1111,7 @@ def main():
elif action == "musl":
build_musl(
client,
- get_image(client, ROOT, BUILD, "gcc"),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
host_platform,
target_triple,
build_options,
@@ -1101,7 +1121,7 @@ def main():
simple_build(
settings,
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
action,
host_platform=host_platform,
target_triple=target_triple,
@@ -1115,7 +1135,7 @@ def main():
build_libedit(
settings,
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
host_platform=host_platform,
target_triple=target_triple,
build_options=build_options,
@@ -1149,7 +1169,7 @@ def main():
simple_build(
settings,
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
action,
host_platform=host_platform,
target_triple=target_triple,
@@ -1162,7 +1182,7 @@ def main():
simple_build(
settings,
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
action,
host_platform=host_platform,
target_triple=target_triple,
@@ -1182,7 +1202,7 @@ def main():
simple_build(
settings,
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
action,
host_platform=host_platform,
target_triple=target_triple,
@@ -1195,7 +1215,7 @@ def main():
simple_build(
settings,
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
action,
host_platform=host_platform,
target_triple=target_triple,
@@ -1208,7 +1228,7 @@ def main():
simple_build(
settings,
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
action,
host_platform=host_platform,
target_triple=target_triple,
@@ -1222,7 +1242,7 @@ def main():
build_tix(
settings,
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
host_platform=host_platform,
target_triple=target_triple,
build_options=build_options,
@@ -1243,7 +1263,7 @@ def main():
simple_build(
settings,
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
action,
host_platform=host_platform,
target_triple=target_triple,
@@ -1256,7 +1276,7 @@ def main():
elif action.startswith("cpython-") and action.endswith("-host"):
build_cpython_host(
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
action[:-5],
host_platform=host_platform,
target_triple=target_triple,
@@ -1275,7 +1295,7 @@ def main():
build_cpython(
settings,
client,
- get_image(client, ROOT, BUILD, docker_image),
+ get_image(client, ROOT, BUILD, docker_image, host_platform),
host_platform=host_platform,
target_triple=target_triple,
build_options=build_options,
diff --git a/cpython-unix/gcc.debian9.Dockerfile b/cpython-unix/gcc.debian9.Dockerfile
new file mode 100644
index 0000000..92d764e
--- /dev/null
+++ b/cpython-unix/gcc.debian9.Dockerfile
@@ -0,0 +1,14 @@
+{% include 'base.debian9.Dockerfile' %}
+RUN ulimit -n 10000 && apt-get install \
+ autoconf \
+ automake \
+ bison \
+ build-essential \
+ gawk \
+ gcc \
+ libtool \
+ make \
+ tar \
+ texinfo \
+ xz-utils \
+ unzip
diff --git a/cpython-unix/targets.yml b/cpython-unix/targets.yml
index 1b47dba..95ef58b 100644
--- a/cpython-unix/targets.yml
+++ b/cpython-unix/targets.yml
@@ -156,6 +156,7 @@ aarch64-apple-ios:
aarch64-unknown-linux-gnu:
host_platforms:
- linux_x86_64
+ - linux_aarch64
pythons_supported:
- '3.9'
- '3.10'
@@ -163,11 +164,16 @@ aarch64-unknown-linux-gnu:
- '3.12'
- '3.13'
- '3.14'
- docker_image_suffix: .cross
- host_cc: /usr/bin/x86_64-linux-gnu-gcc
- host_cxx: /usr/bin/x86_64-linux-gnu-g++
- target_cc: /usr/bin/aarch64-linux-gnu-gcc
- target_cxx: /usr/bin/aarch64-linux-gnu-g++
+ docker_image_suffix: .debian9
+ needs_toolchain: true
+ host_cc: clang
+ host_cxx: clang++
+ target_cc: clang
+ target_cxx: clang++
+ target_cflags:
+ - '-fvisibility=hidden'
+ # Needed to prevent BOLT from crashing.
+ - '-fdebug-default-version=4'
needs:
- autoconf
- bdb
@@ -193,6 +199,11 @@ aarch64-unknown-linux-gnu:
- xz
- zlib
openssl_target: linux-aarch64
+ # Blocked on:
+ # BOLT-ERROR: Cannot relax adr in non-simple function
+ # trampoline_code_table/1. Use --strict option to override
+ # See https://github.com/llvm/llvm-project/issues/146541
+ # bolt_capable: true
arm64-apple-tvos:
host_platforms:
diff --git a/pythonbuild/docker.py b/pythonbuild/docker.py
index 4269b2b..0be78e4 100644
--- a/pythonbuild/docker.py
+++ b/pythonbuild/docker.py
@@ -29,8 +29,10 @@ def write_dockerfiles(source_dir: pathlib.Path, dest_dir: pathlib.Path):
write_if_different(dest_dir / f, data.encode("utf-8"))
-def build_docker_image(client, image_data: bytes, image_dir: pathlib.Path, name):
- image_path = image_dir / ("image-%s" % name)
+def build_docker_image(
+ client, image_data: bytes, image_dir: pathlib.Path, name, host_platform
+):
+ image_path = image_dir / f"image-{name}.{host_platform}"
return ensure_docker_image(client, io.BytesIO(image_data), image_path=image_path)
@@ -66,11 +68,14 @@ def ensure_docker_image(client, fh, image_path=None):
return image
-def get_image(client, source_dir: pathlib.Path, image_dir: pathlib.Path, name):
+def get_image(
+ client, source_dir: pathlib.Path, image_dir: pathlib.Path, name, host_platform
+):
if client is None:
return None
- image_path = image_dir / ("image-%s" % name)
+ image_name = f"image-{name}.{host_platform}"
+ image_path = image_dir / image_name
tar_path = image_path.with_suffix(".tar")
with image_path.open("r") as fh:
@@ -88,7 +93,9 @@ def get_image(client, source_dir: pathlib.Path, image_dir: pathlib.Path, name):
return image_id
else:
- return build_docker_image(client, str(source_dir).encode(), image_dir, name)
+ return build_docker_image(
+ client, str(source_dir).encode(), image_dir, name, host_platform
+ )
def copy_file_to_container(path, container, container_path, archive_path=None):
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index c1cae14..24a9917 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -172,6 +172,13 @@
"version": "14.0.3+20220508",
},
# Remember to update LLVM_URL in src/release.rs whenever upgrading.
+ "llvm-20-aarch64-linux": {
+ "url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-gnu_only-aarch64-unknown-linux-gnu.tar.zst",
+ "size": 255946687,
+ "sha256": "e70753f294b8f83fffbaf07af36857c27ceaef0291cb10f724ada6af11b0a5bc",
+ "version": "20.1.4+20250511",
+ },
+ # Remember to update LLVM_URL in src/release.rs whenever upgrading.
"llvm-20-x86_64-linux": {
"url": "https://github.com/indygreg/toolchain-tools/releases/download/toolchain-bootstrap%2F20250511/llvm-20.1.4+20250511-gnu_only-x86_64-unknown-linux-gnu.tar.zst",
"size": 299883811,
diff --git a/pythonbuild/utils.py b/pythonbuild/utils.py
index a8132ca..0edc11d 100644
--- a/pythonbuild/utils.py
+++ b/pythonbuild/utils.py
@@ -39,6 +39,8 @@ def current_host_platform() -> str:
if sys.platform == "linux":
if machine == "x86_64":
return "linux_x86_64"
+ elif machine == "aarch64":
+ return "linux_aarch64"
else:
raise Exception(f"unsupported Linux host platform: {machine}")
elif sys.platform == "darwin":
@@ -57,6 +59,8 @@ def default_target_triple() -> str:
host = current_host_platform()
if host == "linux_x86_64":
return "x86_64-unknown-linux-gnu"
+ elif host == "linux_aarch64":
+ return "aarch64-unknown-linux-gnu"
elif host == "macos_arm64":
return "aarch64-apple-darwin"
elif host == "macos_x86_64":
@@ -84,6 +88,8 @@ def supported_targets(yaml_path: pathlib.Path):
for host_platform in settings["host_platforms"]:
if sys.platform == "linux" and host_platform == "linux_x86_64":
targets.add(target)
+ elif sys.platform == "linux" and host_platform == "linux_aarch64":
+ targets.add(target)
elif sys.platform == "darwin" and host_platform.startswith("macos_"):
targets.add(target)
@@ -194,7 +200,13 @@ def write_triples_makefiles(
image_suffix = settings.get("docker_image_suffix", "")
+ # On cross builds, we can just use the bare `gcc` image
+ gcc_image_suffix = (
+ image_suffix if not image_suffix.startswith(".cross") else ""
+ )
+
lines.append("DOCKER_IMAGE_BUILD := build%s\n" % image_suffix)
+ lines.append("DOCKER_IMAGE_GCC := gcc%s\n" % gcc_image_suffix)
entry = clang_toolchain(host_platform, triple)
lines.append(
@@ -470,6 +482,8 @@ def clang_toolchain(host_platform: str, target_triple: str) -> str:
return "llvm-14-x86_64-linux"
else:
return "llvm-20-x86_64-linux"
+ elif host_platform == "linux_aarch64":
+ return "llvm-20-aarch64-linux"
elif host_platform == "macos_arm64":
return "llvm-aarch64-macos"
elif host_platform == "macos_x86_64":
From 9bb8bcbeab73b8a962aba962c00f469cbe2cb9b3 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Wed, 2 Jul 2025 12:30:14 -0500
Subject: [PATCH 17/72] Update wanted release targets for
`aarch64-unknown-linux-gnu` (#681)
Following #670
---
src/release.rs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/release.rs b/src/release.rs
index d4f890e..0b67888 100644
--- a/src/release.rs
+++ b/src/release.rs
@@ -168,12 +168,12 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy::
h.insert(
"aarch64-unknown-linux-gnu",
TripleRelease {
- suffixes: linux_suffixes_nopgo.clone(),
- install_only_suffix: "lto",
+ suffixes: linux_suffixes_pgo.clone(),
+ install_only_suffix: "pgo+lto",
python_version_requirement: None,
conditional_suffixes: vec![ConditionalSuffixes {
python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_nopgo_freethreaded.clone(),
+ suffixes: linux_suffixes_pgo_freethreaded.clone(),
}],
},
);
From aaf602236d4cf3e2bd207dfd8f9d45cd0870d58d Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Sat, 5 Jul 2025 11:23:20 -0500
Subject: [PATCH 18/72] Add zstd support for Python 3.14+ on Unix (#682)
This task was deferred from the initial Python 3.14 support. There's
already support on Windows.
---
cpython-unix/Makefile | 4 ++
cpython-unix/build-cpython.sh | 2 +-
cpython-unix/build-zstd.sh | 63 ++++++++++++++++++++++++++++++
cpython-unix/build.py | 1 +
cpython-unix/extension-modules.yml | 7 ++--
cpython-unix/targets.yml | 24 ++++++++++++
src/validation.rs | 4 +-
7 files changed, 98 insertions(+), 7 deletions(-)
create mode 100755 cpython-unix/build-zstd.sh
diff --git a/cpython-unix/Makefile b/cpython-unix/Makefile
index 6e4b007..dcb239a 100644
--- a/cpython-unix/Makefile
+++ b/cpython-unix/Makefile
@@ -236,6 +236,9 @@ $(OUTDIR)/xz-$(XZ_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/
$(OUTDIR)/zlib-$(ZLIB_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-zlib.sh
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) zlib
+$(OUTDIR)/zstd-$(ZSTD_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-zstd.sh
+ $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) zstd
+
PYTHON_HOST_DEPENDS := \
$(PYTHON_DEP_DEPENDS) \
$(HERE)/build-cpython-host.sh \
@@ -272,6 +275,7 @@ PYTHON_DEPENDS_$(1) := \
$$(if $$(NEED_UUID),$$(OUTDIR)/uuid-$$(UUID_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(if $$(NEED_XZ),$$(OUTDIR)/xz-$$(XZ_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(if $$(NEED_ZLIB),$$(OUTDIR)/zlib-$$(ZLIB_VERSION)-$$(PACKAGE_SUFFIX).tar) \
+ $$(if $$(NEED_ZSTD),$$(OUTDIR)/zstd-$$(ZSTD_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(NULL)
ALL_PYTHON_DEPENDS_$(1) = \
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index ce88e6c..4a85ba7 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -1213,7 +1213,7 @@ ${BUILD_PYTHON} ${ROOT}/fix_shebangs.py ${ROOT}/out/python/install
# downstream consumers.
OBJECT_DIRS="Objects Parser Parser/lexer Parser/pegen Parser/tokenizer Programs Python Python/deepfreeze"
OBJECT_DIRS="${OBJECT_DIRS} Modules"
-for ext in _blake2 cjkcodecs _ctypes _ctypes/darwin _decimal _expat _hacl _io _multiprocessing _sha3 _sqlite _sre _testinternalcapi _xxtestfuzz ; do
+for ext in _blake2 cjkcodecs _ctypes _ctypes/darwin _decimal _expat _hacl _io _multiprocessing _sha3 _sqlite _sre _testinternalcapi _xxtestfuzz _zstd; do
OBJECT_DIRS="${OBJECT_DIRS} Modules/${ext}"
done
diff --git a/cpython-unix/build-zstd.sh b/cpython-unix/build-zstd.sh
new file mode 100755
index 0000000..e81ef78
--- /dev/null
+++ b/cpython-unix/build-zstd.sh
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+set -ex
+
+ROOT=`pwd`
+
+export PATH=${TOOLS_PATH}/${TOOLCHAIN}/bin:${TOOLS_PATH}/host/bin:$PATH
+export PREFIX="/tools/deps"
+
+tar -xf zstd-${ZSTD_VERSION}.tar.gz
+
+pushd cpython-source-deps-zstd-${ZSTD_VERSION}/lib
+
+if [ "${CC}" = "musl-clang" ]; then
+ # In order to build the library with SSE2, BMI, and AVX2 intrinstics, we need musl-clang to find
+ # headers that provide access to the intrinsics, as they are not provided by musl. These are
+ # part of the include files that are part of clang. But musl-clang eliminates them from the
+ # default include path. So copy them into place.
+ for h in ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/include/*intrin.h ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/include/{__wmmintrin_aes.h,__wmmintrin_pclmul.h,emmintrin.h,immintrin.h,mm_malloc.h}; do
+ filename=$(basename "$h")
+ if [ -e "${TOOLS_PATH}/host/include/${filename}" ]; then
+ echo "warning: ${filename} already exists"
+ fi
+ cp "$h" ${TOOLS_PATH}/host/include/
+ done
+ EXTRA_TARGET_CFLAGS="${EXTRA_TARGET_CFLAGS} -I${TOOLS_PATH}/host/include/"
+
+ # `qsort_r` is only available in musl 1.2.3+ but we use 1.2.2. The zstd source provides a
+ # fallback implementation, but they do not have a `configure`-style detection of whether
+ # `qsort_r` is actually available so we patch it to include a check for glibc.
+ patch -p1 <suffix, ctx->suffixSize, sizeof(U32),
+ ctx,
+ (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
+-#elif defined(_GNU_SOURCE)
++#elif defined(_GNU_SOURCE) && defined(__GLIBC__)
+ qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32),
+ (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
+ ctx);
+EOF
+fi
+
+CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" make -j ${NUM_CPUS} libzstd.a
+make -j ${NUM_CPUS} install-static DESTDIR=${ROOT}/out
+make -j ${NUM_CPUS} install-includes DESTDIR=${ROOT}/out
+make -j ${NUM_CPUS} install-pc DESTDIR=${ROOT}/out
diff --git a/cpython-unix/build.py b/cpython-unix/build.py
index 01d39b2..b35d172 100755
--- a/cpython-unix/build.py
+++ b/cpython-unix/build.py
@@ -1163,6 +1163,7 @@ def main():
"xtrans",
"xz",
"zlib",
+ "zstd",
):
tools_path = "host" if action in ("m4", "patchelf") else "deps"
diff --git a/cpython-unix/extension-modules.yml b/cpython-unix/extension-modules.yml
index 3d69f04..4b83456 100644
--- a/cpython-unix/extension-modules.yml
+++ b/cpython-unix/extension-modules.yml
@@ -772,15 +772,14 @@ _xxtestfuzz:
- _xxtestfuzz/fuzzer.c
_zstd:
- # Disable on all targets until we add a zstd library
- disabled-targets:
- - .*
minimum-python-version: '3.14'
sources:
- _zstd/_zstdmodule.c
- - _zstd/zdict.c
+ - _zstd/zstddict.c
- _zstd/compressor.c
- _zstd/decompressor.c
+ links:
+ - zstd
_zoneinfo:
minimum-python-version: "3.9"
diff --git a/cpython-unix/targets.yml b/cpython-unix/targets.yml
index 95ef58b..33db80c 100644
--- a/cpython-unix/targets.yml
+++ b/cpython-unix/targets.yml
@@ -108,6 +108,7 @@ aarch64-apple-darwin:
- tk
- uuid
- xz
+ - zstd
openssl_target: darwin64-arm64-cc
aarch64-apple-ios:
@@ -151,6 +152,7 @@ aarch64-apple-ios:
- openssl-3.0
- sqlite
- xz
+ - zstd
openssl_target: ios64-cross
aarch64-unknown-linux-gnu:
@@ -198,6 +200,7 @@ aarch64-unknown-linux-gnu:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-aarch64
# Blocked on:
# BOLT-ERROR: Cannot relax adr in non-simple function
@@ -245,6 +248,7 @@ arm64-apple-tvos:
- openssl-3.0
- sqlite
- xz
+ - zstd
openssl_target: todo
armv7-unknown-linux-gnueabi:
@@ -286,6 +290,7 @@ armv7-unknown-linux-gnueabi:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-armv4
armv7-unknown-linux-gnueabihf:
@@ -327,6 +332,7 @@ armv7-unknown-linux-gnueabihf:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-armv4
mips-unknown-linux-gnu:
@@ -368,6 +374,7 @@ mips-unknown-linux-gnu:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-mips32
mipsel-unknown-linux-gnu:
@@ -409,6 +416,7 @@ mipsel-unknown-linux-gnu:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-mips32
ppc64le-unknown-linux-gnu:
@@ -450,6 +458,7 @@ ppc64le-unknown-linux-gnu:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-ppc64le
riscv64-unknown-linux-gnu:
@@ -491,6 +500,7 @@ riscv64-unknown-linux-gnu:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux64-riscv64
s390x-unknown-linux-gnu:
@@ -532,6 +542,7 @@ s390x-unknown-linux-gnu:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux64-s390x
thumb7k-apple-watchos:
@@ -574,6 +585,7 @@ thumb7k-apple-watchos:
- openssl-3.0
- sqlite
- xz
+ - zstd
openssl_target: todo
# Intel macOS.
@@ -629,6 +641,7 @@ x86_64-apple-darwin:
- tk
- uuid
- xz
+ - zstd
openssl_target: darwin64-x86_64-cc
x86_64-apple-ios:
@@ -672,6 +685,7 @@ x86_64-apple-ios:
- openssl-3.0
- sqlite
- xz
+ - zstd
openssl_target: darwin64-x86_64-cc
x86_64-apple-tvos:
@@ -714,6 +728,7 @@ x86_64-apple-tvos:
- openssl-3.0
- sqlite
- xz
+ - zstd
openssl_target: todo
x86_64-apple-watchos:
@@ -756,6 +771,7 @@ x86_64-apple-watchos:
- openssl-3.0
- sqlite
- xz
+ - zstd
openssl_target: todo
x86_64-unknown-linux-gnu:
@@ -801,6 +817,7 @@ x86_64-unknown-linux-gnu:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-x86_64
bolt_capable: true
@@ -848,6 +865,7 @@ x86_64_v2-unknown-linux-gnu:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-x86_64
bolt_capable: true
@@ -895,6 +913,7 @@ x86_64_v3-unknown-linux-gnu:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-x86_64
bolt_capable: true
@@ -942,6 +961,7 @@ x86_64_v4-unknown-linux-gnu:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-x86_64
bolt_capable: true
@@ -987,6 +1007,7 @@ x86_64-unknown-linux-musl:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-x86_64
x86_64_v2-unknown-linux-musl:
@@ -1032,6 +1053,7 @@ x86_64_v2-unknown-linux-musl:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-x86_64
x86_64_v3-unknown-linux-musl:
@@ -1077,6 +1099,7 @@ x86_64_v3-unknown-linux-musl:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-x86_64
x86_64_v4-unknown-linux-musl:
@@ -1122,4 +1145,5 @@ x86_64_v4-unknown-linux-musl:
- xorgproto
- xz
- zlib
+ - zstd
openssl_target: linux-x86_64
diff --git a/src/validation.rs b/src/validation.rs
index 9084754..5ab7170 100644
--- a/src/validation.rs
+++ b/src/validation.rs
@@ -778,6 +778,7 @@ const GLOBAL_EXTENSIONS_PYTHON_3_14: &[&str] = &[
"_zoneinfo",
"_hmac",
"_types",
+ "_zstd",
];
const GLOBAL_EXTENSIONS_MACOS: &[&str] = &["_scproxy"];
@@ -813,8 +814,7 @@ const GLOBAL_EXTENSIONS_WINDOWS: &[&str] = &[
"winsound",
];
-// TODO(zanieb): Move `_zstd` to non-Windows specific once we add support on Unix.
-const GLOBAL_EXTENSIONS_WINDOWS_3_14: &[&str] = &["_wmi", "_zstd"];
+const GLOBAL_EXTENSIONS_WINDOWS_3_14: &[&str] = &["_wmi"];
const GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13: &[&str] = &["_msi"];
From ec8ee638adb2f1c579a0b4f7a87e73a2949cb204 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sun, 6 Jul 2025 11:06:27 -0500
Subject: [PATCH 19/72] Bump urllib3 from 2.4.0 to 2.5.0 (#665)
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/astral-sh/python-build-standalone/network/alerts).
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
requirements.win.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/requirements.win.txt b/requirements.win.txt
index d37a96f..b9b9a81 100644
--- a/requirements.win.txt
+++ b/requirements.win.txt
@@ -431,9 +431,9 @@ typing-extensions==4.13.2 \
--hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
--hash=sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef
# via -r requirements.in
-urllib3==2.4.0 \
- --hash=sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466 \
- --hash=sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813
+urllib3==2.5.0 \
+ --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \
+ --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc
# via
# docker
# requests
From 9b796d4a5ca2af49761c8e5156fc110b9a70fb53 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Mon, 7 Jul 2025 15:19:14 -0500
Subject: [PATCH 20/72] Bump SQLite to `3.49.1.0` (#667)
Closes https://github.com/astral-sh/python-build-standalone/issues/666
---
cpython-unix/build-sqlite.sh | 15 +++++++++++----
pythonbuild/downloads.py | 10 +++++-----
src/verify_distribution.py | 2 +-
3 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/cpython-unix/build-sqlite.sh b/cpython-unix/build-sqlite.sh
index b045bb8..e01e307 100755
--- a/cpython-unix/build-sqlite.sh
+++ b/cpython-unix/build-sqlite.sh
@@ -14,7 +14,7 @@ pushd sqlite-autoconf-${SQLITE_VERSION}
CONFIGURE_FLAGS="--build=${BUILD_TRIPLE} --host=${TARGET_TRIPLE}"
-CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --prefix /tools/deps --disable-shared"
+CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --prefix=/tools/deps --disable-shared"
if [ "${TARGET_TRIPLE}" = "aarch64-apple-ios" ]; then
CONFIGURE_FLAGS="${CONFIGURE_FLAGS} ac_cv_search_system=no"
@@ -22,7 +22,14 @@ elif [ "${TARGET_TRIPLE}" = "x86_64-apple-ios" ]; then
CONFIGURE_FLAGS="${CONFIGURE_FLAGS} ac_cv_search_system=no"
fi
-CFLAGS="${EXTRA_TARGET_CFLAGS} -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS3_TOKENIZER -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure ${CONFIGURE_FLAGS}
+# The SQLite autosetup looks for the C++ compiler if the variable is set and will fail if it's not
+# found, even if it's not needed. We don't actually have a C++ compiler in some builds, so ensure
+# it's not looked for.
+unset CXX
-make -j ${NUM_CPUS}
-make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out
+CC_FOR_BUILD="${HOST_CC}" CFLAGS="${EXTRA_TARGET_CFLAGS} -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS3_TOKENIZER -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure ${CONFIGURE_FLAGS}
+
+make -j ${NUM_CPUS} libsqlite3.a
+make install-lib DESTDIR=${ROOT}/out
+make install-headers DESTDIR=${ROOT}/out
+make install-pc DESTDIR=${ROOT}/out
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index 24a9917..a208ce5 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -295,11 +295,11 @@
},
# Remember to update verify_distribution.py when version changed.
"sqlite": {
- "url": "https://www.sqlite.org/2024/sqlite-autoconf-3470100.tar.gz",
- "size": 3328564,
- "sha256": "416a6f45bf2cacd494b208fdee1beda509abda951d5f47bc4f2792126f01b452",
- "version": "3470100",
- "actual_version": "3.47.1.0",
+ "url": "https://www.sqlite.org/2025/sqlite-autoconf-3490100.tar.gz",
+ "size": 3226385,
+ "sha256": "106642d8ccb36c5f7323b64e4152e9b719f7c0215acf5bfeac3d5e7f97b59254",
+ "version": "3490100",
+ "actual_version": "3.49.1.0",
"library_names": ["sqlite3"],
"licenses": [],
"license_file": "LICENSE.sqlite.txt",
diff --git a/src/verify_distribution.py b/src/verify_distribution.py
index 2131d7a..1ac2381 100644
--- a/src/verify_distribution.py
+++ b/src/verify_distribution.py
@@ -114,7 +114,7 @@ def test_hashlib(self):
def test_sqlite(self):
import sqlite3
- self.assertEqual(sqlite3.sqlite_version_info, (3, 47, 1))
+ self.assertEqual(sqlite3.sqlite_version_info, (3, 49, 1))
# Optional SQLite3 features are enabled.
conn = sqlite3.connect(":memory:")
From 625ad3072a441c1dec616b23cc0d8ea95db04e79 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 7 Jul 2025 15:19:24 -0500
Subject: [PATCH 21/72] Bump the python group across 1 directory with 6 updates
(#688)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps the python group with 6 updates in the / directory:
| Package | From | To |
| --- | --- | --- |
| [certifi](https://github.com/certifi/python-certifi) | `2025.4.26` |
`2025.6.15` |
| [pyyaml](https://github.com/yaml/pyyaml) | `6.0.1` | `6.0.2` |
| [rpds-py](https://github.com/crate-py/rpds) | `0.25.1` | `0.26.0` |
| [typing-extensions](https://github.com/python/typing_extensions) |
`4.13.2` | `4.14.1` |
| [mypy](https://github.com/python/mypy) | `1.16.0` | `1.16.1` |
| [ruff](https://github.com/astral-sh/ruff) | `0.11.13` | `0.12.2` |
Updates `certifi` from 2025.4.26 to 2025.6.15
Commits
e767d59
2025.06.15 (#357)
3e70765
Bump actions/setup-python from 5.5.0 to 5.6.0
9afd2ff
Bump actions/download-artifact from 4.2.1 to 4.3.0
d7c816c
remove code that's no longer required that 3.7 is our minimum (#351)
1899613
Declare setuptools as the build backend in pyproject.toml (#350)
c874142
update CI for ubuntu 20.04 deprecation (#348)
- See full diff in compare
view
Updates `pyyaml` from 6.0.1 to 6.0.2
Release notes
Sourced from pyyaml's
releases.
6.0.2
What's Changed
- Support for Cython 3.x and Python 3.13.
Full Changelog: https://github.com/yaml/pyyaml/compare/6.0.1...6.0.2
6.0.2rc1
- Support for extension build with Cython 3.x
- Support for Python 3.13
- Added PyPI wheels for musllinux on aarch64
Changelog
Sourced from pyyaml's
changelog.
6.0.2 (2024-08-06)
Commits
Updates `rpds-py` from 0.25.1 to 0.26.0
Release notes
Sourced from rpds-py's
releases.
v0.26.0
What's Changed
Full Changelog: https://github.com/crate-py/rpds/compare/v0.25.1...v0.26.0
Commits
ff9278f
Tag a release.
d2f69ef
Update requirements.
58ee607
Merge pull request #146
from edgarrmondragon/136-require-maturin-1.9-pep639
5433ab6
Require maturin>=1.9.0 to ensure support for PEP 639
7557e53
Merge pull request #144
from crate-py/dependabot/github_actions/github/codeql...
d0963ae
Merge pull request #145
from crate-py/dependabot/github_actions/astral-sh/set...
513ec22
Bump astral-sh/setup-uv from 6.3.0 to 6.3.1
cbb4277
Bump github/codeql-action from 3.29.0 to 3.29.2
25123e9
Merge pull request #143
from crate-py/dependabot/github_actions/PyO3/maturin-...
7a59bb7
Merge pull request #142
from crate-py/dependabot/github_actions/astral-sh/set...
- Additional commits viewable in compare
view
Updates `typing-extensions` from 4.13.2 to 4.14.1
Release notes
Sourced from typing-extensions's
releases.
4.14.1
Release 4.14.1 (July 4, 2025)
- Fix usage of
typing_extensions.TypedDict nested inside
other types
(e.g., typing.Type[typing_extensions.TypedDict]). This is
not allowed by the
type system but worked on older versions, so we maintain support.
4.14.0
This release adds several new features, including experimental
support for inline typed dictionaries (PEP 764) and sentinels (PEP 661), and support for
changes in Python 3.14. In addition, Python 3.8 is no longer
supported.
Changes since 4.14.0rc1:
- Remove
__or__ and __ror__ methods from
typing_extensions.Sentinel
on Python versions <3.10. PEP 604 was introduced in Python 3.10, and
typing_extensions does not generally attempt to backport
PEP-604 methods
to prior versions.
- Further update
typing_extensions.evaluate_forward_ref
with changes in Python 3.14.
Changes included in 4.14.0rc1:
- Drop support for Python 3.8 (including PyPy-3.8). Patch by Victorien Plot.
- Do not attempt to re-export names that have been removed from
typing,
anticipating the removal of typing.no_type_check_decorator
in Python 3.15.
Patch by Jelle Zijlstra.
- Update
typing_extensions.Format,
typing_extensions.evaluate_forward_ref, and
typing_extensions.TypedDict to align
with changes in Python 3.14. Patches by Jelle Zijlstra.
- Fix tests for Python 3.14 and 3.15. Patches by Jelle Zijlstra.
New features:
- Add support for inline typed dictionaries (PEP 764).
Patch by Victorien Plot.
- Add
typing_extensions.Reader and
typing_extensions.Writer. Patch by
Sebastian Rittau.
- Add support for sentinels (PEP 661). Patch by
Victorien Plot.
4.14.0rc1
Major changes:
- Drop support for Python 3.8 (including PyPy-3.8). Patch by Victorien Plot.
- Do not attempt to re-export names that have been removed from
typing,
anticipating the removal of typing.no_type_check_decorator
in Python 3.15.
Patch by Jelle Zijlstra.
- Update
typing_extensions.Format,
typing_extensions.evaluate_forward_ref, and
typing_extensions.TypedDict to align
with changes in Python 3.14. Patches by Jelle Zijlstra.
- Fix tests for Python 3.14 and 3.15. Patches by Jelle Zijlstra.
... (truncated)
Changelog
Sourced from typing-extensions's
changelog.
Release 4.14.1 (July 4, 2025)
- Fix usage of
typing_extensions.TypedDict nested inside
other types
(e.g., typing.Type[typing_extensions.TypedDict]). This is
not allowed by the
type system but worked on older versions, so we maintain support.
Release 4.14.0 (June 2, 2025)
Changes since 4.14.0rc1:
- Remove
__or__ and __ror__ methods from
typing_extensions.Sentinel
on Python versions <3.10. PEP 604 was introduced in Python 3.10, and
typing_extensions does not generally attempt to backport
PEP-604 methods
to prior versions.
- Further update
typing_extensions.evaluate_forward_ref
with changes in Python 3.14.
Release 4.14.0rc1 (May 24, 2025)
- Drop support for Python 3.8 (including PyPy-3.8). Patch by Victorien Plot.
- Do not attempt to re-export names that have been removed from
typing,
anticipating the removal of typing.no_type_check_decorator
in Python 3.15.
Patch by Jelle Zijlstra.
- Update
typing_extensions.Format,
typing_extensions.evaluate_forward_ref, and
typing_extensions.TypedDict to align
with changes in Python 3.14. Patches by Jelle Zijlstra.
- Fix tests for Python 3.14 and 3.15. Patches by Jelle Zijlstra.
New features:
- Add support for inline typed dictionaries (PEP 764).
Patch by Victorien Plot.
- Add
typing_extensions.Reader and
typing_extensions.Writer. Patch by
Sebastian Rittau.
- Add support for sentinels (PEP 661). Patch by
Victorien Plot.
Commits
Updates `mypy` from 1.16.0 to 1.16.1
Commits
Updates `ruff` from 0.11.13 to 0.12.2
Release notes
Sourced from ruff's
releases.
0.12.2
Release Notes
Preview features
- [
flake8-pyi] Expand Optional[A] to A
| None (PYI016) (#18572)
- [
pyupgrade] Mark UP008 fix safe if no
comments are in range (#18683)
Bug fixes
- [
flake8-comprehensions] Fix C420 to
prepend whitespace when needed (#18616)
- [
perflint] Fix PERF403 panic on attribute
or subscription loop variable (#19042)
- [
pydocstyle] Fix D413 infinite loop for
parenthesized docstring (#18930)
- [
pylint] Fix PLW0108 autofix introducing a
syntax error when the lambda's body contains an assignment expression
(#18678)
- [
refurb] Fix false positive on empty tuples
(FURB168) (#19058)
- [
ruff] Allow more field calls from
attrs (RUF009) (#19021)
- [
ruff] Fix syntax error introduced for an empty string
followed by a u-prefixed string (UP025) (#18899)
Rule changes
- [
flake8-executable] Allow uvx in shebang
line (EXE003) (#18967)
- [
pandas] Avoid flagging PD002 if
pandas is not imported (#18963)
- [
pyupgrade] Avoid PEP-604 unions with
typing.NamedTuple (UP007, UP045)
(#18682)
Documentation
- Document link between
import-outside-top-level
(PLC0415) and
lint.flake8-tidy-imports.banned-module-level-imports (#18733)
- Fix description of the
format.skip-magic-trailing-comma
example (#19095)
- [
airflow] Make AIR302 example error
out-of-the-box (#18988)
- [
airflow] Make AIR312 example error
out-of-the-box (#18989)
- [
flake8-annotations] Make ANN401 example
error out-of-the-box (#18974)
- [
flake8-async] Make ASYNC100 example error
out-of-the-box (#18993)
- [
flake8-async] Make ASYNC105 example error
out-of-the-box (#19002)
- [
flake8-async] Make ASYNC110 example error
out-of-the-box (#18975)
- [
flake8-async] Make ASYNC210 example error
out-of-the-box (#18977)
- [
flake8-async] Make ASYNC220,
ASYNC221, and ASYNC222 examples error
out-of-the-box (#18978)
- [
flake8-async] Make ASYNC251 example error
out-of-the-box (#18990)
- [
flake8-bandit] Make S201 example error
out-of-the-box (#19017)
- [
flake8-bandit] Make S604 and
S609 examples error out-of-the-box (#19049)
- [
flake8-bugbear] Make B028 example error
out-of-the-box (#19054)
- [
flake8-bugbear] Make B911 example error
out-of-the-box (#19051)
- [
flake8-datetimez] Make DTZ011 example
error out-of-the-box (#19055)
- [
flake8-datetimez] Make DTZ901 example
error out-of-the-box (#19056)
- [
flake8-pyi] Make PYI032 example error
out-of-the-box (#19061)
- [
flake8-pyi] Make example error out-of-the-box
(PYI014, PYI015) (#19097)
- [
flake8-pyi] Make example error out-of-the-box
(PYI042) (#19101)
- [
flake8-pyi] Make example error out-of-the-box
(PYI059) (#19080)
- [
flake8-pyi] Make example error out-of-the-box
(PYI062) (#19079)
- [
flake8-pytest-style] Make example error out-of-the-box
(PT023) (#19104)
- [
flake8-pytest-style] Make example error out-of-the-box
(PT030) (#19105)
... (truncated)
Changelog
Sourced from ruff's
changelog.
0.12.2
Preview features
- [
flake8-pyi] Expand Optional[A] to A
| None (PYI016) (#18572)
- [
pyupgrade] Mark UP008 fix safe if no
comments are in range (#18683)
Bug fixes
- [
flake8-comprehensions] Fix C420 to
prepend whitespace when needed (#18616)
- [
perflint] Fix PERF403 panic on attribute
or subscription loop variable (#19042)
- [
pydocstyle] Fix D413 infinite loop for
parenthesized docstring (#18930)
- [
pylint] Fix PLW0108 autofix introducing a
syntax error when the lambda's body contains an assignment expression
(#18678)
- [
refurb] Fix false positive on empty tuples
(FURB168) (#19058)
- [
ruff] Allow more field calls from
attrs (RUF009) (#19021)
- [
ruff] Fix syntax error introduced for an empty string
followed by a u-prefixed string (UP025) (#18899)
Rule changes
- [
flake8-executable] Allow uvx in shebang
line (EXE003) (#18967)
- [
pandas] Avoid flagging PD002 if
pandas is not imported (#18963)
- [
pyupgrade] Avoid PEP-604 unions with
typing.NamedTuple (UP007, UP045)
(#18682)
Documentation
- Document link between
import-outside-top-level
(PLC0415) and
lint.flake8-tidy-imports.banned-module-level-imports (#18733)
- Fix description of the
format.skip-magic-trailing-comma
example (#19095)
- [
airflow] Make AIR302 example error
out-of-the-box (#18988)
- [
airflow] Make AIR312 example error
out-of-the-box (#18989)
- [
flake8-annotations] Make ANN401 example
error out-of-the-box (#18974)
- [
flake8-async] Make ASYNC100 example error
out-of-the-box (#18993)
- [
flake8-async] Make ASYNC105 example error
out-of-the-box (#19002)
- [
flake8-async] Make ASYNC110 example error
out-of-the-box (#18975)
- [
flake8-async] Make ASYNC210 example error
out-of-the-box (#18977)
- [
flake8-async] Make ASYNC220,
ASYNC221, and ASYNC222 examples error
out-of-the-box (#18978)
- [
flake8-async] Make ASYNC251 example error
out-of-the-box (#18990)
- [
flake8-bandit] Make S201 example error
out-of-the-box (#19017)
- [
flake8-bandit] Make S604 and
S609 examples error out-of-the-box (#19049)
- [
flake8-bugbear] Make B028 example error
out-of-the-box (#19054)
- [
flake8-bugbear] Make B911 example error
out-of-the-box (#19051)
- [
flake8-datetimez] Make DTZ011 example
error out-of-the-box (#19055)
- [
flake8-datetimez] Make DTZ901 example
error out-of-the-box (#19056)
- [
flake8-pyi] Make PYI032 example error
out-of-the-box (#19061)
- [
flake8-pyi] Make example error out-of-the-box
(PYI014, PYI015) (#19097)
- [
flake8-pyi] Make example error out-of-the-box
(PYI042) (#19101)
- [
flake8-pyi] Make example error out-of-the-box
(PYI059) (#19080)
- [
flake8-pyi] Make example error out-of-the-box
(PYI062) (#19079)
- [
flake8-pytest-style] Make example error out-of-the-box
(PT023) (#19104)
- [
flake8-pytest-style] Make example error out-of-the-box
(PT030) (#19105)
- [
flake8-quotes] Make example error out-of-the-box
(Q003) (#19106)
... (truncated)
Commits
9bee837
Bump 0.12.2 (#19126)
1c6717b
Filter private symbols from stubs if they are internal types (#19121)
1b813cd
Fix description of the format.skip-magic-trailing-comma
example (#19095)
b00f68a
[ruff] Allow more field calls from
attrs (RUF009) (#19021)
710c60f
[flake8-pytest-style] Make example error out-of-the-box
(PT023) (#19104)
811e25d
[flake8-pytest-style] Make example error out-of-the-box
(PT030) (#19105)
b78af2d
[flake8-quotes] Make example error out-of-the-box
(Q003) (#19106)
4f36f06
Document link between import-outside-top-level (PLC0415)
and `lint.flake8-t...
2589a29
[flake8-simplify] Make example error out-of-the-box
(SIM113) (#19109)
26bb8f7
[flake8-simplify] Make example error out-of-the-box
(SIM401) (#19110)
- Additional commits viewable in compare
view
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore ` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore ` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore ` will
remove the ignore condition of the specified dependency and ignore
conditions
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
requirements.dev.txt | 104 ++++++------
requirements.win.txt | 381 +++++++++++++++++++++++--------------------
2 files changed, 257 insertions(+), 228 deletions(-)
diff --git a/requirements.dev.txt b/requirements.dev.txt
index 68171eb..0876769 100644
--- a/requirements.dev.txt
+++ b/requirements.dev.txt
@@ -198,39 +198,39 @@ markupsafe==3.0.2 \
# via
# -r requirements.txt
# jinja2
-mypy==1.16.0 \
- --hash=sha256:021a68568082c5b36e977d54e8f1de978baf401a33884ffcea09bd8e88a98f4c \
- --hash=sha256:089bedc02307c2548eb51f426e085546db1fa7dd87fbb7c9fa561575cf6eb1ff \
- --hash=sha256:09a8da6a0ee9a9770b8ff61b39c0bb07971cda90e7297f4213741b48a0cc8d93 \
- --hash=sha256:0b07e107affb9ee6ce1f342c07f51552d126c32cd62955f59a7db94a51ad12c0 \
- --hash=sha256:15486beea80be24ff067d7d0ede673b001d0d684d0095803b3e6e17a886a2a92 \
- --hash=sha256:29e1499864a3888bca5c1542f2d7232c6e586295183320caa95758fc84034031 \
- --hash=sha256:2e7e0ad35275e02797323a5aa1be0b14a4d03ffdb2e5f2b0489fa07b89c67b21 \
- --hash=sha256:4086883a73166631307fdd330c4a9080ce24913d4f4c5ec596c601b3a4bdd777 \
- --hash=sha256:54066fed302d83bf5128632d05b4ec68412e1f03ef2c300434057d66866cea4b \
- --hash=sha256:55f9076c6ce55dd3f8cd0c6fff26a008ca8e5131b89d5ba6d86bd3f47e736eeb \
- --hash=sha256:6a2322896003ba66bbd1318c10d3afdfe24e78ef12ea10e2acd985e9d684a666 \
- --hash=sha256:7909541fef256527e5ee9c0a7e2aeed78b6cda72ba44298d1334fe7881b05c5c \
- --hash=sha256:82d056e6faa508501af333a6af192c700b33e15865bda49611e3d7d8358ebea2 \
- --hash=sha256:84b94283f817e2aa6350a14b4a8fb2a35a53c286f97c9d30f53b63620e7af8ab \
- --hash=sha256:936ccfdd749af4766be824268bfe22d1db9eb2f34a3ea1d00ffbe5b5265f5491 \
- --hash=sha256:9f826aaa7ff8443bac6a494cf743f591488ea940dd360e7dd330e30dd772a5ab \
- --hash=sha256:a5fcfdb7318c6a8dd127b14b1052743b83e97a970f0edb6c913211507a255e20 \
- --hash=sha256:a7e32297a437cc915599e0578fa6bc68ae6a8dc059c9e009c628e1c47f91495d \
- --hash=sha256:a9e056237c89f1587a3be1a3a70a06a698d25e2479b9a2f57325ddaaffc3567b \
- --hash=sha256:afe420c9380ccec31e744e8baff0d406c846683681025db3531b32db56962d52 \
- --hash=sha256:b4968f14f44c62e2ec4a038c8797a87315be8df7740dc3ee8d3bfe1c6bf5dba8 \
- --hash=sha256:bd4e1ebe126152a7bbaa4daedd781c90c8f9643c79b9748caa270ad542f12bec \
- --hash=sha256:c5436d11e89a3ad16ce8afe752f0f373ae9620841c50883dc96f8b8805620b13 \
- --hash=sha256:c6fb60cbd85dc65d4d63d37cb5c86f4e3a301ec605f606ae3a9173e5cf34997b \
- --hash=sha256:d045d33c284e10a038f5e29faca055b90eee87da3fc63b8889085744ebabb5a1 \
- --hash=sha256:e71d6f0090c2256c713ed3d52711d01859c82608b5d68d4fa01a3fe30df95571 \
- --hash=sha256:eb14a4a871bb8efb1e4a50360d4e3c8d6c601e7a31028a2c79f9bb659b63d730 \
- --hash=sha256:eb5fbc8063cb4fde7787e4c0406aa63094a34a2daf4673f359a1fb64050e9cb2 \
- --hash=sha256:f2622af30bf01d8fc36466231bdd203d120d7a599a6d88fb22bdcb9dbff84090 \
- --hash=sha256:f2ed0e0847a80655afa2c121835b848ed101cc7b8d8d6ecc5205aedc732b1436 \
- --hash=sha256:f56236114c425620875c7cf71700e3d60004858da856c6fc78998ffe767b73d3 \
- --hash=sha256:feec38097f71797da0231997e0de3a58108c51845399669ebc532c815f93866b
+mypy==1.16.1 \
+ --hash=sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359 \
+ --hash=sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507 \
+ --hash=sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c \
+ --hash=sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f \
+ --hash=sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15 \
+ --hash=sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6 \
+ --hash=sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383 \
+ --hash=sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b \
+ --hash=sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6 \
+ --hash=sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca \
+ --hash=sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4 \
+ --hash=sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574 \
+ --hash=sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79 \
+ --hash=sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc \
+ --hash=sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee \
+ --hash=sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40 \
+ --hash=sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da \
+ --hash=sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37 \
+ --hash=sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9 \
+ --hash=sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab \
+ --hash=sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069 \
+ --hash=sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72 \
+ --hash=sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536 \
+ --hash=sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d \
+ --hash=sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a \
+ --hash=sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be \
+ --hash=sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438 \
+ --hash=sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd \
+ --hash=sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782 \
+ --hash=sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea \
+ --hash=sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b \
+ --hash=sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d
# via -r requirements.dev.in
mypy-extensions==1.0.0 \
--hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \
@@ -417,25 +417,25 @@ rpds-py==0.22.3 \
# -r requirements.txt
# jsonschema
# referencing
-ruff==0.11.13 \
- --hash=sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629 \
- --hash=sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432 \
- --hash=sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514 \
- --hash=sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3 \
- --hash=sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc \
- --hash=sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46 \
- --hash=sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9 \
- --hash=sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492 \
- --hash=sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b \
- --hash=sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165 \
- --hash=sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71 \
- --hash=sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc \
- --hash=sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250 \
- --hash=sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a \
- --hash=sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48 \
- --hash=sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b \
- --hash=sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7 \
- --hash=sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933
+ruff==0.12.2 \
+ --hash=sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be \
+ --hash=sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e \
+ --hash=sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d \
+ --hash=sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a \
+ --hash=sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d \
+ --hash=sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922 \
+ --hash=sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1 \
+ --hash=sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12 \
+ --hash=sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342 \
+ --hash=sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da \
+ --hash=sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce \
+ --hash=sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04 \
+ --hash=sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b \
+ --hash=sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9 \
+ --hash=sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc \
+ --hash=sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4 \
+ --hash=sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e \
+ --hash=sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639
# via -r requirements.dev.in
six==1.17.0 \
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
diff --git a/requirements.win.txt b/requirements.win.txt
index b9b9a81..faa0135 100644
--- a/requirements.win.txt
+++ b/requirements.win.txt
@@ -6,9 +6,9 @@ attrs==25.3.0 \
# via
# jsonschema
# referencing
-certifi==2025.4.26 \
- --hash=sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6 \
- --hash=sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3
+certifi==2025.6.15 \
+ --hash=sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057 \
+ --hash=sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b
# via requests
charset-normalizer==3.4.2 \
--hash=sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4 \
@@ -205,58 +205,60 @@ pywin32==310 \
--hash=sha256:c3e78706e4229b915a0821941a84e7ef420bf2b77e08c9dae3c76fd03fd2ae3d \
--hash=sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33
# via docker
-pyyaml==6.0.1 \
- --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \
- --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \
- --hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \
- --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \
- --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \
- --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \
- --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \
- --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \
- --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \
- --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \
- --hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \
- --hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \
- --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \
- --hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \
- --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \
- --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \
- --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \
- --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \
- --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \
- --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \
- --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \
- --hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \
- --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \
- --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \
- --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \
- --hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \
- --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \
- --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \
- --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \
- --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \
- --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \
- --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \
- --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \
- --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \
- --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \
- --hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \
- --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \
- --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \
- --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \
- --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \
- --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \
- --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \
- --hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \
- --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \
- --hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \
- --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \
- --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \
- --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \
- --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \
- --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
- --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
+pyyaml==6.0.2 \
+ --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
+ --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \
+ --hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \
+ --hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \
+ --hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \
+ --hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \
+ --hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \
+ --hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \
+ --hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \
+ --hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \
+ --hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \
+ --hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \
+ --hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \
+ --hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \
+ --hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \
+ --hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \
+ --hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \
+ --hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \
+ --hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \
+ --hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \
+ --hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \
+ --hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \
+ --hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \
+ --hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \
+ --hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \
+ --hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \
+ --hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \
+ --hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \
+ --hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \
+ --hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \
+ --hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \
+ --hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \
+ --hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \
+ --hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \
+ --hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \
+ --hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \
+ --hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \
+ --hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \
+ --hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \
+ --hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \
+ --hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \
+ --hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \
+ --hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \
+ --hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \
+ --hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \
+ --hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \
+ --hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \
+ --hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \
+ --hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \
+ --hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \
+ --hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \
+ --hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \
+ --hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4
# via -r requirements.in
referencing==0.36.2 \
--hash=sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa \
@@ -268,124 +270,151 @@ requests==2.32.4 \
--hash=sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c \
--hash=sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422
# via docker
-rpds-py==0.25.1 \
- --hash=sha256:0317177b1e8691ab5879f4f33f4b6dc55ad3b344399e23df2e499de7b10a548d \
- --hash=sha256:036ded36bedb727beeabc16dc1dad7cb154b3fa444e936a03b67a86dc6a5066e \
- --hash=sha256:048893e902132fd6548a2e661fb38bf4896a89eea95ac5816cf443524a85556f \
- --hash=sha256:0701942049095741a8aeb298a31b203e735d1c61f4423511d2b1a41dcd8a16da \
- --hash=sha256:083a9513a33e0b92cf6e7a6366036c6bb43ea595332c1ab5c8ae329e4bcc0a9c \
- --hash=sha256:09eab132f41bf792c7a0ea1578e55df3f3e7f61888e340779b06050a9a3f16e9 \
- --hash=sha256:0e6a327af8ebf6baba1c10fadd04964c1965d375d318f4435d5f3f9651550f4a \
- --hash=sha256:0eb90e94f43e5085623932b68840b6f379f26db7b5c2e6bcef3179bd83c9330f \
- --hash=sha256:114a07e85f32b125404f28f2ed0ba431685151c037a26032b213c882f26eb908 \
- --hash=sha256:115874ae5e2fdcfc16b2aedc95b5eef4aebe91b28e7e21951eda8a5dc0d3461b \
- --hash=sha256:140f61d9bed7839446bdd44852e30195c8e520f81329b4201ceead4d64eb3a9f \
- --hash=sha256:1521031351865e0181bc585147624d66b3b00a84109b57fcb7a779c3ec3772cd \
- --hash=sha256:1c0c434a53714358532d13539272db75a5ed9df75a4a090a753ac7173ec14e11 \
- --hash=sha256:1d1fadd539298e70cac2f2cb36f5b8a65f742b9b9f1014dd4ea1f7785e2470bf \
- --hash=sha256:1de336a4b164c9188cb23f3703adb74a7623ab32d20090d0e9bf499a2203ad65 \
- --hash=sha256:1ee3e26eb83d39b886d2cb6e06ea701bba82ef30a0de044d34626ede51ec98b0 \
- --hash=sha256:245550f5a1ac98504147cba96ffec8fabc22b610742e9150138e5d60774686d7 \
- --hash=sha256:2a40046a529cc15cef88ac5ab589f83f739e2d332cb4d7399072242400ed68c9 \
- --hash=sha256:2c2cd1a4b0c2b8c5e31ffff50d09f39906fe351389ba143c195566056c13a7ea \
- --hash=sha256:2cb9e5b5e26fc02c8a4345048cd9998c2aca7c2712bd1b36da0c72ee969a3523 \
- --hash=sha256:33358883a4490287e67a2c391dfaea4d9359860281db3292b6886bf0be3d8692 \
- --hash=sha256:35634369325906bcd01577da4c19e3b9541a15e99f31e91a02d010816b49bfda \
- --hash=sha256:35a8d1a24b5936b35c5003313bc177403d8bdef0f8b24f28b1c4a255f94ea992 \
- --hash=sha256:3af5b4cc10fa41e5bc64e5c198a1b2d2864337f8fcbb9a67e747e34002ce812b \
- --hash=sha256:3bcce0edc1488906c2d4c75c94c70a0417e83920dd4c88fec1078c94843a6ce9 \
- --hash=sha256:3c5b317ecbd8226887994852e85de562f7177add602514d4ac40f87de3ae45a8 \
- --hash=sha256:3c6564c0947a7f52e4792983f8e6cf9bac140438ebf81f527a21d944f2fd0a40 \
- --hash=sha256:3ebd879ab996537fc510a2be58c59915b5dd63bccb06d1ef514fee787e05984a \
- --hash=sha256:3f0b1798cae2bbbc9b9db44ee068c556d4737911ad53a4e5093d09d04b3bbc24 \
- --hash=sha256:401ca1c4a20cc0510d3435d89c069fe0a9ae2ee6495135ac46bdd49ec0495763 \
- --hash=sha256:454601988aab2c6e8fd49e7634c65476b2b919647626208e376afcd22019eeb8 \
- --hash=sha256:4593c4eae9b27d22df41cde518b4b9e4464d139e4322e2127daa9b5b981b76be \
- --hash=sha256:45e484db65e5380804afbec784522de84fa95e6bb92ef1bd3325d33d13efaebd \
- --hash=sha256:48d64155d02127c249695abb87d39f0faf410733428d499867606be138161d65 \
- --hash=sha256:4fbb0dbba559959fcb5d0735a0f87cdbca9e95dac87982e9b95c0f8f7ad10255 \
- --hash=sha256:4fd52d3455a0aa997734f3835cbc4c9f32571345143960e7d7ebfe7b5fbfa3b2 \
- --hash=sha256:50f2c501a89c9a5f4e454b126193c5495b9fb441a75b298c60591d8a2eb92e1b \
- --hash=sha256:58f77c60956501a4a627749a6dcb78dac522f249dd96b5c9f1c6af29bfacfb66 \
- --hash=sha256:5a3ddb74b0985c4387719fc536faced33cadf2172769540c62e2a94b7b9be1c4 \
- --hash=sha256:5c4a128527fe415d73cf1f70a9a688d06130d5810be69f3b553bf7b45e8acf79 \
- --hash=sha256:5d473be2b13600b93a5675d78f59e63b51b1ba2d0476893415dfbb5477e65b31 \
- --hash=sha256:5d9e40f32745db28c1ef7aad23f6fc458dc1e29945bd6781060f0d15628b8ddf \
- --hash=sha256:5f048bbf18b1f9120685c6d6bb70cc1a52c8cc11bdd04e643d28d3be0baf666d \
- --hash=sha256:605ffe7769e24b1800b4d024d24034405d9404f0bc2f55b6db3362cd34145a6f \
- --hash=sha256:6099263f526efff9cf3883dfef505518730f7a7a93049b1d90d42e50a22b4793 \
- --hash=sha256:659d87430a8c8c704d52d094f5ba6fa72ef13b4d385b7e542a08fc240cb4a559 \
- --hash=sha256:666fa7b1bd0a3810a7f18f6d3a25ccd8866291fbbc3c9b912b917a6715874bb9 \
- --hash=sha256:68f6f060f0bbdfb0245267da014d3a6da9be127fe3e8cc4a68c6f833f8a23bb1 \
- --hash=sha256:6d273f136e912aa101a9274c3145dcbddbe4bac560e77e6d5b3c9f6e0ed06d34 \
- --hash=sha256:6d50841c425d16faf3206ddbba44c21aa3310a0cebc3c1cdfc3e3f4f9f6f5728 \
- --hash=sha256:771c16060ff4e79584dc48902a91ba79fd93eade3aa3a12d6d2a4aadaf7d542b \
- --hash=sha256:785ffacd0ee61c3e60bdfde93baa6d7c10d86f15655bd706c89da08068dc5038 \
- --hash=sha256:796ad874c89127c91970652a4ee8b00d56368b7e00d3477f4415fe78164c8000 \
- --hash=sha256:79dc317a5f1c51fd9c6a0c4f48209c6b8526d0524a6904fc1076476e79b00f98 \
- --hash=sha256:7c9409b47ba0650544b0bb3c188243b83654dfe55dcc173a86832314e1a6a35d \
- --hash=sha256:7d779b325cc8238227c47fbc53964c8cc9a941d5dbae87aa007a1f08f2f77b23 \
- --hash=sha256:816568614ecb22b18a010c7a12559c19f6fe993526af88e95a76d5a60b8b75fb \
- --hash=sha256:8378fa4a940f3fb509c081e06cb7f7f2adae8cf46ef258b0e0ed7519facd573e \
- --hash=sha256:85608eb70a659bf4c1142b2781083d4b7c0c4e2c90eff11856a9754e965b2540 \
- --hash=sha256:85fc223d9c76cabe5d0bff82214459189720dc135db45f9f66aa7cffbf9ff6c1 \
- --hash=sha256:88ec04afe0c59fa64e2f6ea0dd9657e04fc83e38de90f6de201954b4d4eb59bd \
- --hash=sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3 \
- --hash=sha256:89706d0683c73a26f76a5315d893c051324d771196ae8b13e6ffa1ffaf5e574f \
- --hash=sha256:89c24300cd4a8e4a51e55c31a8ff3918e6651b241ee8876a42cc2b2a078533ba \
- --hash=sha256:8c742af695f7525e559c16f1562cf2323db0e3f0fbdcabdf6865b095256b2d40 \
- --hash=sha256:8dbd586bfa270c1103ece2109314dd423df1fa3d9719928b5d09e4840cec0d72 \
- --hash=sha256:8eb8c84ecea987a2523e057c0d950bcb3f789696c0499290b8d7b3107a719d78 \
- --hash=sha256:921954d7fbf3fccc7de8f717799304b14b6d9a45bbeec5a8d7408ccbf531faf5 \
- --hash=sha256:9a46c2fb2545e21181445515960006e85d22025bd2fe6db23e76daec6eb689fe \
- --hash=sha256:9c006f3aadeda131b438c3092124bd196b66312f0caa5823ef09585a669cf449 \
- --hash=sha256:9ceca1cf097ed77e1a51f1dbc8d174d10cb5931c188a4505ff9f3e119dfe519b \
- --hash=sha256:9e5fc7484fa7dce57e25063b0ec9638ff02a908304f861d81ea49273e43838c1 \
- --hash=sha256:9f2f48ab00181600ee266a095fe815134eb456163f7d6699f525dee471f312cf \
- --hash=sha256:9fca84a15333e925dd59ce01da0ffe2ffe0d6e5d29a9eeba2148916d1824948c \
- --hash=sha256:a49e1d7a4978ed554f095430b89ecc23f42014a50ac385eb0c4d163ce213c325 \
- --hash=sha256:a58d1ed49a94d4183483a3ce0af22f20318d4a1434acee255d683ad90bf78129 \
- --hash=sha256:a61d0b2c7c9a0ae45732a77844917b427ff16ad5464b4d4f5e4adb955f582890 \
- --hash=sha256:a714bf6e5e81b0e570d01f56e0c89c6375101b8463999ead3a93a5d2a4af91fa \
- --hash=sha256:a7b74e92a3b212390bdce1d93da9f6488c3878c1d434c5e751cbc202c5e09500 \
- --hash=sha256:a8bd2f19e312ce3e1d2c635618e8a8d8132892bb746a7cf74780a489f0f6cdcb \
- --hash=sha256:b0be9965f93c222fb9b4cc254235b3b2b215796c03ef5ee64f995b1b69af0762 \
- --hash=sha256:b24bf3cd93d5b6ecfbedec73b15f143596c88ee249fa98cefa9a9dc9d92c6f28 \
- --hash=sha256:b5ffe453cde61f73fea9430223c81d29e2fbf412a6073951102146c84e19e34c \
- --hash=sha256:bc120d1132cff853ff617754196d0ac0ae63befe7c8498bd67731ba368abe451 \
- --hash=sha256:bd035756830c712b64725a76327ce80e82ed12ebab361d3a1cdc0f51ea21acb0 \
- --hash=sha256:bffcf57826d77a4151962bf1701374e0fc87f536e56ec46f1abdd6a903354042 \
- --hash=sha256:c2013ee878c76269c7b557a9a9c042335d732e89d482606990b70a839635feb7 \
- --hash=sha256:c4feb9211d15d9160bc85fa72fed46432cdc143eb9cf6d5ca377335a921ac37b \
- --hash=sha256:c8980cde3bb8575e7c956a530f2c217c1d6aac453474bf3ea0f9c89868b531b6 \
- --hash=sha256:c98f126c4fc697b84c423e387337d5b07e4a61e9feac494362a59fd7a2d9ed80 \
- --hash=sha256:ccc6f3ddef93243538be76f8e47045b4aad7a66a212cd3a0f23e34469473d36b \
- --hash=sha256:ccfa689b9246c48947d31dd9d8b16d89a0ecc8e0e26ea5253068efb6c542b76e \
- --hash=sha256:cda776f1967cb304816173b30994faaf2fd5bcb37e73118a47964a02c348e1bc \
- --hash=sha256:ce4c8e485a3c59593f1a6f683cf0ea5ab1c1dc94d11eea5619e4fb5228b40fbd \
- --hash=sha256:d3c10228d6cf6fe2b63d2e7985e94f6916fa46940df46b70449e9ff9297bd3d1 \
- --hash=sha256:d4ca54b9cf9d80b4016a67a0193ebe0bcf29f6b0a96f09db942087e294d3d4c2 \
- --hash=sha256:d4cb2b3ddc16710548801c6fcc0cfcdeeff9dafbc983f77265877793f2660309 \
- --hash=sha256:d50e4864498a9ab639d6d8854b25e80642bd362ff104312d9770b05d66e5fb13 \
- --hash=sha256:d74ec9bc0e2feb81d3f16946b005748119c0f52a153f6db6a29e8cd68636f295 \
- --hash=sha256:d8222acdb51a22929c3b2ddb236b69c59c72af4019d2cba961e2f9add9b6e634 \
- --hash=sha256:db58483f71c5db67d643857404da360dce3573031586034b7d59f245144cc192 \
- --hash=sha256:dc3c1ff0abc91444cd20ec643d0f805df9a3661fcacf9c95000329f3ddf268a4 \
- --hash=sha256:dd326a81afe332ede08eb39ab75b301d5676802cdffd3a8f287a5f0b694dc3f5 \
- --hash=sha256:dec21e02e6cc932538b5203d3a8bd6aa1480c98c4914cb88eea064ecdbc6396a \
- --hash=sha256:e1dafef8df605fdb46edcc0bf1573dea0d6d7b01ba87f85cd04dc855b2b4479e \
- --hash=sha256:e2f6a2347d3440ae789505693a02836383426249d5293541cd712e07e7aecf54 \
- --hash=sha256:e37caa8cdb3b7cf24786451a0bdb853f6347b8b92005eeb64225ae1db54d1c2b \
- --hash=sha256:e43a005671a9ed5a650f3bc39e4dbccd6d4326b24fb5ea8be5f3a43a6f576c72 \
- --hash=sha256:e5e2f7280d8d0d3ef06f3ec1b4fd598d386cc6f0721e54f09109a8132182fbfe \
- --hash=sha256:e87798852ae0b37c88babb7f7bbbb3e3fecc562a1c340195b44c7e24d403e380 \
- --hash=sha256:ee86d81551ec68a5c25373c5643d343150cc54672b5e9a0cafc93c1870a53954 \
- --hash=sha256:f251bf23deb8332823aef1da169d5d89fa84c89f67bdfb566c49dea1fccfd50d \
- --hash=sha256:f3d86373ff19ca0441ebeb696ef64cb58b8b5cbacffcda5a0ec2f3911732a194 \
- --hash=sha256:f4ad628b5174d5315761b67f212774a32f5bad5e61396d38108bd801c0a8f5d9 \
- --hash=sha256:f70316f760174ca04492b5ab01be631a8ae30cadab1d1081035136ba12738cfa \
- --hash=sha256:f73ce1512e04fbe2bc97836e89830d6b4314c171587a99688082d090f934d20a \
- --hash=sha256:ff7c23ba0a88cb7b104281a99476cccadf29de2a0ef5ce864959a52675b1ca83
+rpds-py==0.26.0 \
+ --hash=sha256:0919f38f5542c0a87e7b4afcafab6fd2c15386632d249e9a087498571250abe3 \
+ --hash=sha256:093d63b4b0f52d98ebae33b8c50900d3d67e0666094b1be7a12fffd7f65de74b \
+ --hash=sha256:0a0b60701f2300c81b2ac88a5fb893ccfa408e1c4a555a77f908a2596eb875a5 \
+ --hash=sha256:0c71c2f6bf36e61ee5c47b2b9b5d47e4d1baad6426bfed9eea3e858fc6ee8806 \
+ --hash=sha256:0dc23bbb3e06ec1ea72d515fb572c1fea59695aefbffb106501138762e1e915e \
+ --hash=sha256:0dfa6115c6def37905344d56fb54c03afc49104e2ca473d5dedec0f6606913b4 \
+ --hash=sha256:12bff2ad9447188377f1b2794772f91fe68bb4bbfa5a39d7941fbebdbf8c500f \
+ --hash=sha256:1533b7eb683fb5f38c1d68a3c78f5fdd8f1412fa6b9bf03b40f450785a0ab915 \
+ --hash=sha256:1766b5724c3f779317d5321664a343c07773c8c5fd1532e4039e6cc7d1a815be \
+ --hash=sha256:181ef9b6bbf9845a264f9aa45c31836e9f3c1f13be565d0d010e964c661d1e2b \
+ --hash=sha256:183f857a53bcf4b1b42ef0f57ca553ab56bdd170e49d8091e96c51c3d69ca696 \
+ --hash=sha256:191aa858f7d4902e975d4cf2f2d9243816c91e9605070aeb09c0a800d187e323 \
+ --hash=sha256:1a8b0dd8648709b62d9372fc00a57466f5fdeefed666afe3fea5a6c9539a0331 \
+ --hash=sha256:1c962145c7473723df9722ba4c058de12eb5ebedcb4e27e7d902920aa3831ee8 \
+ --hash=sha256:1cc81d14ddfa53d7f3906694d35d54d9d3f850ef8e4e99ee68bc0d1e5fed9a9c \
+ --hash=sha256:1d815d48b1804ed7867b539236b6dd62997850ca1c91cad187f2ddb1b7bbef19 \
+ --hash=sha256:1e6c15d2080a63aaed876e228efe4f814bc7889c63b1e112ad46fdc8b368b9e1 \
+ --hash=sha256:20ab1ae4fa534f73647aad289003f1104092890849e0266271351922ed5574f8 \
+ --hash=sha256:20dae58a859b0906f0685642e591056f1e787f3a8b39c8e8749a45dc7d26bdb0 \
+ --hash=sha256:238e8c8610cb7c29460e37184f6799547f7e09e6a9bdbdab4e8edb90986a2318 \
+ --hash=sha256:24a4146ccb15be237fdef10f331c568e1b0e505f8c8c9ed5d67759dac58ac246 \
+ --hash=sha256:257d011919f133a4746958257f2c75238e3ff54255acd5e3e11f3ff41fd14256 \
+ --hash=sha256:2a343f91b17097c546b93f7999976fd6c9d5900617aa848c81d794e062ab302b \
+ --hash=sha256:2abe21d8ba64cded53a2a677e149ceb76dcf44284202d737178afe7ba540c1eb \
+ --hash=sha256:2c03c9b0c64afd0320ae57de4c982801271c0c211aa2d37f3003ff5feb75bb04 \
+ --hash=sha256:2c9c1b92b774b2e68d11193dc39620d62fd8ab33f0a3c77ecdabe19c179cdbc1 \
+ --hash=sha256:3021933c2cb7def39d927b9862292e0f4c75a13d7de70eb0ab06efed4c508c19 \
+ --hash=sha256:3100b3090269f3a7ea727b06a6080d4eb7439dca4c0e91a07c5d133bb1727ea7 \
+ --hash=sha256:313cfcd6af1a55a286a3c9a25f64af6d0e46cf60bc5798f1db152d97a216ff6f \
+ --hash=sha256:35e9a70a0f335371275cdcd08bc5b8051ac494dd58bff3bbfb421038220dc871 \
+ --hash=sha256:38721d4c9edd3eb6670437d8d5e2070063f305bfa2d5aa4278c51cedcd508a84 \
+ --hash=sha256:390e3170babf42462739a93321e657444f0862c6d722a291accc46f9d21ed04e \
+ --hash=sha256:39bfea47c375f379d8e87ab4bb9eb2c836e4f2069f0f65731d85e55d74666387 \
+ --hash=sha256:3ac51b65e8dc76cf4949419c54c5528adb24fc721df722fd452e5fbc236f5c40 \
+ --hash=sha256:3c0909c5234543ada2515c05dc08595b08d621ba919629e94427e8e03539c958 \
+ --hash=sha256:3da5852aad63fa0c6f836f3359647870e21ea96cf433eb393ffa45263a170d44 \
+ --hash=sha256:3e1157659470aa42a75448b6e943c895be8c70531c43cb78b9ba990778955582 \
+ --hash=sha256:4019a9d473c708cf2f16415688ef0b4639e07abaa569d72f74745bbeffafa2c7 \
+ --hash=sha256:43f10b007033f359bc3fa9cd5e6c1e76723f056ffa9a6b5c117cc35720a80292 \
+ --hash=sha256:49028aa684c144ea502a8e847d23aed5e4c2ef7cadfa7d5eaafcb40864844b7a \
+ --hash=sha256:4916dc96489616a6f9667e7526af8fa693c0fdb4f3acb0e5d9f4400eb06a47ba \
+ --hash=sha256:4a59e5bc386de021f56337f757301b337d7ab58baa40174fb150accd480bc953 \
+ --hash=sha256:4b1f66eb81eab2e0ff5775a3a312e5e2e16bf758f7b06be82fb0d04078c7ac51 \
+ --hash=sha256:4c5fe114a6dd480a510b6d3661d09d67d1622c4bf20660a474507aaee7eeeee9 \
+ --hash=sha256:4c70c70f9169692b36307a95f3d8c0a9fcd79f7b4a383aad5eaa0e9718b79b37 \
+ --hash=sha256:4d11382bcaf12f80b51d790dee295c56a159633a8e81e6323b16e55d81ae37e9 \
+ --hash=sha256:4f01a5d6444a3258b00dc07b6ea4733e26f8072b788bef750baa37b370266137 \
+ --hash=sha256:4f789e32fa1fb6a7bf890e0124e7b42d1e60d28ebff57fe806719abb75f0e9a3 \
+ --hash=sha256:4feb7511c29f8442cbbc28149a92093d32e815a28aa2c50d333826ad2a20fdf0 \
+ --hash=sha256:511d15193cbe013619dd05414c35a7dedf2088fcee93c6bbb7c77859765bd4e8 \
+ --hash=sha256:519067e29f67b5c90e64fb1a6b6e9d2ec0ba28705c51956637bac23a2f4ddae1 \
+ --hash=sha256:521ccf56f45bb3a791182dc6b88ae5f8fa079dd705ee42138c76deb1238e554e \
+ --hash=sha256:529c8156d7506fba5740e05da8795688f87119cce330c244519cf706a4a3d618 \
+ --hash=sha256:582462833ba7cee52e968b0341b85e392ae53d44c0f9af6a5927c80e539a8b67 \
+ --hash=sha256:5963b72ccd199ade6ee493723d18a3f21ba7d5b957017607f815788cef50eaf1 \
+ --hash=sha256:59b2093224a18c6508d95cfdeba8db9cbfd6f3494e94793b58972933fcee4c6d \
+ --hash=sha256:5afaddaa8e8c7f1f7b4c5c725c0070b6eed0228f705b90a1732a48e84350f4e9 \
+ --hash=sha256:5afea17ab3a126006dc2f293b14ffc7ef3c85336cf451564a0515ed7648033da \
+ --hash=sha256:5e09330b21d98adc8ccb2dbb9fc6cb434e8908d4c119aeaa772cb1caab5440a0 \
+ --hash=sha256:6188de70e190847bb6db3dc3981cbadff87d27d6fe9b4f0e18726d55795cee9b \
+ --hash=sha256:68ffcf982715f5b5b7686bdd349ff75d422e8f22551000c24b30eaa1b7f7ae84 \
+ --hash=sha256:696764a5be111b036256c0b18cd29783fab22154690fc698062fc1b0084b511d \
+ --hash=sha256:69a607203441e07e9a8a529cff1d5b73f6a160f22db1097211e6212a68567d11 \
+ --hash=sha256:69b312fecc1d017b5327afa81d4da1480f51c68810963a7336d92203dbb3d4f1 \
+ --hash=sha256:69f0c0a3df7fd3a7eec50a00396104bb9a843ea6d45fcc31c2d5243446ffd7a7 \
+ --hash=sha256:6a1cb5d6ce81379401bbb7f6dbe3d56de537fb8235979843f0d53bc2e9815a79 \
+ --hash=sha256:6d3498ad0df07d81112aa6ec6c95a7e7b1ae00929fb73e7ebee0f3faaeabad2f \
+ --hash=sha256:72a8d9564a717ee291f554eeb4bfeafe2309d5ec0aa6c475170bdab0f9ee8e88 \
+ --hash=sha256:777c62479d12395bfb932944e61e915741e364c843afc3196b694db3d669fcd0 \
+ --hash=sha256:77a7711fa562ba2da1aa757e11024ad6d93bad6ad7ede5afb9af144623e5f76a \
+ --hash=sha256:79061ba1a11b6a12743a2b0f72a46aa2758613d454aa6ba4f5a265cc48850158 \
+ --hash=sha256:7a48af25d9b3c15684059d0d1fc0bc30e8eee5ca521030e2bffddcab5be40226 \
+ --hash=sha256:7ab504c4d654e4a29558eaa5bb8cea5fdc1703ea60a8099ffd9c758472cf913f \
+ --hash=sha256:7bdb17009696214c3b66bb3590c6d62e14ac5935e53e929bcdbc5a495987a84f \
+ --hash=sha256:7da84c2c74c0f5bc97d853d9e17bb83e2dcafcff0dc48286916001cc114379a1 \
+ --hash=sha256:801a71f70f9813e82d2513c9a96532551fce1e278ec0c64610992c49c04c2dad \
+ --hash=sha256:824e6d3503ab990d7090768e4dfd9e840837bae057f212ff9f4f05ec6d1975e7 \
+ --hash=sha256:82b165b07f416bdccf5c84546a484cc8f15137ca38325403864bfdf2b5b72f6a \
+ --hash=sha256:84cfbd4d4d2cdeb2be61a057a258d26b22877266dd905809e94172dff01a42ae \
+ --hash=sha256:84d142d2d6cf9b31c12aa4878d82ed3b2324226270b89b676ac62ccd7df52d08 \
+ --hash=sha256:87a5531de9f71aceb8af041d72fc4cab4943648d91875ed56d2e629bef6d4c03 \
+ --hash=sha256:893b022bfbdf26d7bedb083efeea624e8550ca6eb98bf7fea30211ce95b9201a \
+ --hash=sha256:894514d47e012e794f1350f076c427d2347ebf82f9b958d554d12819849a369d \
+ --hash=sha256:8a7898b6ca3b7d6659e55cdac825a2e58c638cbf335cde41f4619e290dd0ad11 \
+ --hash=sha256:8ad7fd2258228bf288f2331f0a6148ad0186b2e3643055ed0db30990e59817a6 \
+ --hash=sha256:92c8db839367ef16a662478f0a2fe13e15f2227da3c1430a782ad0f6ee009ec9 \
+ --hash=sha256:941c1cfdf4799d623cf3aa1d326a6b4fdb7a5799ee2687f3516738216d2262fb \
+ --hash=sha256:9bc596b30f86dc6f0929499c9e574601679d0341a0108c25b9b358a042f51bca \
+ --hash=sha256:9c55b0a669976cf258afd718de3d9ad1b7d1fe0a91cd1ab36f38b03d4d4aeaaf \
+ --hash=sha256:9da4e873860ad5bab3291438525cae80169daecbfafe5657f7f5fb4d6b3f96b9 \
+ --hash=sha256:9def736773fd56b305c0eef698be5192c77bfa30d55a0e5885f80126c4831a15 \
+ --hash=sha256:9dfbe56b299cf5875b68eb6f0ebaadc9cac520a1989cac0db0765abfb3709c19 \
+ --hash=sha256:9e851920caab2dbcae311fd28f4313c6953993893eb5c1bb367ec69d9a39e7ed \
+ --hash=sha256:9e8cb77286025bdb21be2941d64ac6ca016130bfdcd228739e8ab137eb4406ed \
+ --hash=sha256:a547e21c5610b7e9093d870be50682a6a6cf180d6da0f42c47c306073bfdbbf6 \
+ --hash=sha256:a90a13408a7a856b87be8a9f008fff53c5080eea4e4180f6c2e546e4a972fb5d \
+ --hash=sha256:a9a63785467b2d73635957d32a4f6e73d5e4df497a16a6392fa066b753e87387 \
+ --hash=sha256:aa81873e2c8c5aa616ab8e017a481a96742fdf9313c40f14338ca7dbf50cb55f \
+ --hash=sha256:ac64f4b2bdb4ea622175c9ab7cf09444e412e22c0e02e906978b3b488af5fde8 \
+ --hash=sha256:aea1f9741b603a8d8fedb0ed5502c2bc0accbc51f43e2ad1337fe7259c2b77a5 \
+ --hash=sha256:b0afb8cdd034150d4d9f53926226ed27ad15b7f465e93d7468caaf5eafae0d37 \
+ --hash=sha256:b37a04d9f52cb76b6b78f35109b513f6519efb481d8ca4c321f6a3b9580b3f45 \
+ --hash=sha256:b5f7a446ddaf6ca0fad9a5535b56fbfc29998bf0e0b450d174bbec0d600e1d72 \
+ --hash=sha256:b6d9e5a2ed9c4988c8f9b28b3bc0e3e5b1aaa10c28d210a594ff3a8c02742daf \
+ --hash=sha256:b6e2c12160c72aeda9d1283e612f68804621f448145a210f1bf1d79151c47090 \
+ --hash=sha256:b818a592bd69bfe437ee8368603d4a2d928c34cffcdf77c2e761a759ffd17d20 \
+ --hash=sha256:c1851f429b822831bd2edcbe0cfd12ee9ea77868f8d3daf267b189371671c80e \
+ --hash=sha256:c1fb0cda2abcc0ac62f64e2ea4b4e64c57dfd6b885e693095460c61bde7bb18e \
+ --hash=sha256:c5ab0ee51f560d179b057555b4f601b7df909ed31312d301b99f8b9fc6028284 \
+ --hash=sha256:c70d9ec912802ecfd6cd390dadb34a9578b04f9bcb8e863d0a7598ba5e9e7ccc \
+ --hash=sha256:c741107203954f6fc34d3066d213d0a0c40f7bb5aafd698fb39888af277c70d8 \
+ --hash=sha256:ca3f059f4ba485d90c8dc75cb5ca897e15325e4e609812ce57f896607c1c0867 \
+ --hash=sha256:caf51943715b12af827696ec395bfa68f090a4c1a1d2509eb4e2cb69abbbdb33 \
+ --hash=sha256:cb28c1f569f8d33b2b5dcd05d0e6ef7005d8639c54c2f0be824f05aedf715255 \
+ --hash=sha256:cdad4ea3b4513b475e027be79e5a0ceac8ee1c113a1a11e5edc3c30c29f964d8 \
+ --hash=sha256:cf47cfdabc2194a669dcf7a8dbba62e37a04c5041d2125fae0233b720da6f05c \
+ --hash=sha256:d04cab0a54b9dba4d278fe955a1390da3cf71f57feb78ddc7cb67cbe0bd30323 \
+ --hash=sha256:d422b945683e409000c888e384546dbab9009bb92f7c0b456e217988cf316107 \
+ --hash=sha256:d80bf832ac7b1920ee29a426cdca335f96a2b5caa839811803e999b41ba9030d \
+ --hash=sha256:da619979df60a940cd434084355c514c25cf8eb4cf9a508510682f6c851a4f7a \
+ --hash=sha256:dafd4c44b74aa4bed4b250f1aed165b8ef5de743bcca3b88fc9619b6087093d2 \
+ --hash=sha256:dca83c498b4650a91efcf7b88d669b170256bf8017a5db6f3e06c2bf031f57e0 \
+ --hash=sha256:de2713f48c1ad57f89ac25b3cb7daed2156d8e822cf0eca9b96a6f990718cc41 \
+ --hash=sha256:de4ed93a8c91debfd5a047be327b7cc8b0cc6afe32a716bbbc4aedca9e2a83af \
+ --hash=sha256:df52098cde6d5e02fa75c1f6244f07971773adb4a26625edd5c18fee906fa84d \
+ --hash=sha256:dfbf280da5f876d0b00c81f26bedce274e72a678c28845453885a9b3c22ae632 \
+ --hash=sha256:e3730a48e5622e598293eee0762b09cff34dd3f271530f47b0894891281f051d \
+ --hash=sha256:e5162afc9e0d1f9cae3b577d9c29ddbab3505ab39012cb794d94a005825bde21 \
+ --hash=sha256:e5d524d68a474a9688336045bbf76cb0def88549c1b2ad9dbfec1fb7cfbe9170 \
+ --hash=sha256:e99685fc95d386da368013e7fb4269dd39c30d99f812a8372d62f244f662709c \
+ --hash=sha256:ea89a2458a1a75f87caabefe789c87539ea4e43b40f18cff526052e35bbb4fdf \
+ --hash=sha256:ec671691e72dff75817386aa02d81e708b5a7ec0dec6669ec05213ff6b77e1bd \
+ --hash=sha256:eed5ac260dd545fbc20da5f4f15e7efe36a55e0e7cf706e4ec005b491a9546a0 \
+ --hash=sha256:f14440b9573a6f76b4ee4770c13f0b5921f71dde3b6fcb8dabbefd13b7fe05d7 \
+ --hash=sha256:f405c93675d8d4c5ac87364bb38d06c988e11028a64b52a47158a355079661f3 \
+ --hash=sha256:f53ec51f9d24e9638a40cabb95078ade8c99251945dad8d57bf4aabe86ecee35 \
+ --hash=sha256:f61a9326f80ca59214d1cceb0a09bb2ece5b2563d4e0cd37bfd5515c28510674 \
+ --hash=sha256:f7bf2496fa563c046d05e4d232d7b7fd61346e2402052064b773e5c378bf6f73 \
+ --hash=sha256:fbaa70553ca116c77717f513e08815aec458e6b69a028d4028d403b3bc84ff37 \
+ --hash=sha256:fc3e55a7db08dc9a6ed5fb7103019d2c1a38a349ac41901f9f66d7f95750942f \
+ --hash=sha256:fc921b96fa95a097add244da36a1d9e4f3039160d1d30f1b35837bf108c21136 \
+ --hash=sha256:fd0641abca296bc1a00183fe44f7fced8807ed49d501f188faa642d0e4975b83 \
+ --hash=sha256:feac1045b3327a45944e7dcbeb57530339f6b17baff154df51ef8b0da34c8c12 \
+ --hash=sha256:ff110acded3c22c033e637dd8896e411c7d3a11289b2edf041f86663dbc791e9
# via
# jsonschema
# referencing
@@ -427,9 +456,9 @@ tomli==2.2.1 \
--hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \
--hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7
# via -r requirements.in
-typing-extensions==4.13.2 \
- --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
- --hash=sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef
+typing-extensions==4.14.1 \
+ --hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \
+ --hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76
# via -r requirements.in
urllib3==2.5.0 \
--hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \
From f39d4ebe840c05036ed6d2e01a346abc80dfd642 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Tue, 8 Jul 2025 15:36:07 -0500
Subject: [PATCH 22/72] Bump to 3.14.0b4 (#689)
---
cpython-unix/build-cpython.sh | 7 +-
cpython-unix/patch-jit-cflags-314.patch | 90 -------------------------
pythonbuild/downloads.py | 8 +--
3 files changed, 6 insertions(+), 99 deletions(-)
delete mode 100644 cpython-unix/patch-jit-cflags-314.patch
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index 4a85ba7..cc93f0a 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -480,11 +480,8 @@ if [ -n "${CPYTHON_OPTIMIZED}" ]; then
# Respect CFLAGS during JIT compilation.
#
- # Backports https://github.com/python/cpython/pull/134276 which we're trying to get released
- # in 3.14, but is currently only in 3.15+.
- if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]; then
- patch -p1 -i ${ROOT}/patch-jit-cflags-314.patch
- elif [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then
+ # Backports https://github.com/python/cpython/pull/134276
+ if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" && -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_13}" ]]; then
patch -p1 -i ${ROOT}/patch-jit-cflags-313.patch
fi
diff --git a/cpython-unix/patch-jit-cflags-314.patch b/cpython-unix/patch-jit-cflags-314.patch
deleted file mode 100644
index a75563b..0000000
--- a/cpython-unix/patch-jit-cflags-314.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-diff --git a/Misc/NEWS.d/next/Build/2025-05-19-18-09-20.gh-issue-134273.ZAliyy.rst b/Misc/NEWS.d/next/Build/2025-05-19-18-09-20.gh-issue-134273.ZAliyy.rst
-new file mode 100644
-index 00000000000..3eb13cefbe6
---- /dev/null
-+++ b/Misc/NEWS.d/next/Build/2025-05-19-18-09-20.gh-issue-134273.ZAliyy.rst
-@@ -0,0 +1 @@
-+Add support for configuring compiler flags for the JIT with ``CFLAGS_JIT``
-diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py
-index d0a1c081ffe..b383e39da19 100644
---- a/Tools/jit/_targets.py
-+++ b/Tools/jit/_targets.py
-@@ -10,6 +10,7 @@
- import sys
- import tempfile
- import typing
-+import shlex
-
- import _llvm
- import _schema
-@@ -46,6 +47,7 @@ class _Target(typing.Generic[_S, _R]):
- stable: bool = False
- debug: bool = False
- verbose: bool = False
-+ cflags: str = ""
- known_symbols: dict[str, int] = dataclasses.field(default_factory=dict)
- pyconfig_dir: pathlib.Path = pathlib.Path.cwd().resolve()
-
-@@ -62,6 +64,7 @@ def _compute_digest(self) -> str:
- hasher = hashlib.sha256()
- hasher.update(self.triple.encode())
- hasher.update(self.debug.to_bytes())
-+ hasher.update(self.cflags.encode())
- # These dependencies are also reflected in _JITSources in regen.targets:
- hasher.update(PYTHON_EXECUTOR_CASES_C_H.read_bytes())
- hasher.update((self.pyconfig_dir / "pyconfig.h").read_bytes())
-@@ -155,6 +158,8 @@ async def _compile(
- f"{o}",
- f"{c}",
- *self.args,
-+ # Allow user-provided CFLAGS to override any defaults
-+ *shlex.split(self.cflags),
- ]
- await _llvm.run("clang", args, echo=self.verbose)
- return await self._parse(o)
-diff --git a/Tools/jit/build.py b/Tools/jit/build.py
-index 1afd0c76bad..a0733005929 100644
---- a/Tools/jit/build.py
-+++ b/Tools/jit/build.py
-@@ -39,11 +39,15 @@
- parser.add_argument(
- "-v", "--verbose", action="store_true", help="echo commands as they are run"
- )
-+ parser.add_argument(
-+ "--cflags", help="additional flags to pass to the compiler", default=""
-+ )
- args = parser.parse_args()
- for target in args.target:
- target.debug = args.debug
- target.force = args.force
- target.verbose = args.verbose
-+ target.cflags = args.cflags
- target.pyconfig_dir = args.pyconfig_dir
- target.build(
- comment=comment,
-diff --git a/configure b/configure
-index 029bf527da4..fef9f2d7da9 100755
---- a/configure
-+++ b/configure
-@@ -10863,7 +10863,7 @@ then :
-
- else case e in #(
- e) as_fn_append CFLAGS_NODIST " $jit_flags"
-- REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir ."
-+ REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --cflags=\"$CFLAGS_JIT\""
- JIT_STENCILS_H="jit_stencils.h"
- if test "x$Py_DEBUG" = xtrue
- then :
-diff --git a/configure.ac b/configure.ac
-index 371b2e8ed73..cc37a636c52 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -2776,7 +2776,7 @@ AS_VAR_IF([jit_flags],
- [],
- [AS_VAR_APPEND([CFLAGS_NODIST], [" $jit_flags"])
- AS_VAR_SET([REGEN_JIT_COMMAND],
-- ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir ."])
-+ ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py ${ARCH_TRIPLES:-$host} --output-dir . --pyconfig-dir . --cflags=\"$CFLAGS_JIT\""])
- AS_VAR_SET([JIT_STENCILS_H], ["jit_stencils.h"])
- AS_VAR_IF([Py_DEBUG],
- [true],
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index a208ce5..20d5c98 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -82,10 +82,10 @@
"python_tag": "cp313",
},
"cpython-3.14": {
- "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0b3.tar.xz",
- "size": 23626928,
- "sha256": "c6f48bf51f01f50d87007a445dd7afe4a4c7a87ab482570be924c1ddfd0d3682",
- "version": "3.14.0b3",
+ "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0b4.tar.xz",
+ "size": 23641472,
+ "sha256": "15e123e056abebba6de5e73cfa304459a8c82cafa85d4fc7fc6de80e6a3e1b39",
+ "version": "3.14.0b4",
"licenses": ["Python-2.0", "CNRI-Python"],
"license_file": "LICENSE.cpython.txt",
"python_tag": "cp314",
From e996271b4ac836282d9f7d997b0ef8ecfca34336 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Wed, 9 Jul 2025 07:24:56 -0500
Subject: [PATCH 23/72] Drop `.sha256` files from releases (#691)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
GitHub has started enforcing a 1000 file limit, which breaks us.
I first encountered it in CI during the release:
https://github.com/astral-sh/python-build-standalone/actions/runs/16156480423
Then got to an actual error message via the CLI:
```
❯ gh release upload 20250708 dist/cpython-3.14.0b4-riscv64-unknown-linux-gnu-freethreaded+lto-20250708T1536.tar.zst
HTTP 422: Validation Failed (https://uploads.github.com/repos/astral-sh/python-build-standalone/releases/230978017/assets?label=&name=cpython-3.14.0b4-riscv64-unknown-linux-gnu-freethreaded%2Blto-20250708T1536.tar.zst)
file_count limited to 1000 assets per release
```
You can see they documented a limit recently:
https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases#storage-and-bandwidth-quotas
https://web.archive.org/web/20250629152715/https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases
---
src/github.rs | 8 --------
1 file changed, 8 deletions(-)
diff --git a/src/github.rs b/src/github.rs
index 0d3bc97..2dfbba5 100644
--- a/src/github.rs
+++ b/src/github.rs
@@ -505,14 +505,6 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<(
file_data,
dry_run,
));
- fs.push(upload_release_artifact(
- &raw_client,
- token.clone(),
- &release,
- format!("{}.sha256", dest),
- Bytes::copy_from_slice(format!("{}\n", digest).as_bytes()),
- dry_run,
- ));
}
let mut buffered = futures::stream::iter(fs).buffer_unordered(16);
From 62461bd628e8e6d0b406f4486222e388ba9d2724 Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Thu, 10 Jul 2025 17:24:39 -0400
Subject: [PATCH 24/72] Add missing Makefile dependency for binutils -> gcc
image (#692)
This was unintentionally removed in 21cf744dda2d0e19329950a81a07d9067179f976.
---
cpython-unix/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cpython-unix/Makefile b/cpython-unix/Makefile
index dcb239a..40c34a2 100644
--- a/cpython-unix/Makefile
+++ b/cpython-unix/Makefile
@@ -79,7 +79,7 @@ $(OUTDIR)/image-%.$(HOST_PLATFORM).tar: $(OUTDIR)/%.Dockerfile
$(RUN_BUILD) --toolchain image-$*
endif
-$(OUTDIR)/binutils-$(BINUTILS_VERSION)-$(HOST_PLATFORM).tar: $(HERE)/build-binutils.sh
+$(OUTDIR)/binutils-$(BINUTILS_VERSION)-$(HOST_PLATFORM).tar: $(OUTDIR)/image-$(DOCKER_IMAGE_GCC).$(HOST_PLATFORM).tar $(HERE)/build-binutils.sh
$(RUN_BUILD) --toolchain --docker-image $(DOCKER_IMAGE_GCC) binutils
$(OUTDIR)/$(CLANG_FILENAME):
From 7797c3898aa2cc03f6b92dc1370f6e8fd0797345 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Fri, 11 Jul 2025 10:39:07 -0500
Subject: [PATCH 25/72] Enable fts4, fts5, rtree, and geopoly in SQLite (#694)
And add some regression tests.
Co-authored-by: Geoffrey Thomas
---
cpython-unix/build-sqlite.sh | 14 +++++++++++++-
src/verify_distribution.py | 9 +++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/cpython-unix/build-sqlite.sh b/cpython-unix/build-sqlite.sh
index e01e307..ef7c6a6 100755
--- a/cpython-unix/build-sqlite.sh
+++ b/cpython-unix/build-sqlite.sh
@@ -27,7 +27,19 @@ fi
# it's not looked for.
unset CXX
-CC_FOR_BUILD="${HOST_CC}" CFLAGS="${EXTRA_TARGET_CFLAGS} -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS3_TOKENIZER -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure ${CONFIGURE_FLAGS}
+CC_FOR_BUILD="${HOST_CC}" \
+CFLAGS="${EXTRA_TARGET_CFLAGS} \
+ -DSQLITE_ENABLE_DBSTAT_VTAB \
+ -DSQLITE_ENABLE_FTS3 \
+ -DSQLITE_ENABLE_FTS3_PARENTHESIS \
+ -DSQLITE_ENABLE_FTS3_TOKENIZER \
+ -DSQLITE_ENABLE_FTS4 \
+ -DSQLITE_ENABLE_FTS5 \
+ -DSQLITE_ENABLE_GEOPOLY \
+ -DSQLITE_ENABLE_RTREE \
+ -fPIC" \
+CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" \
+LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure ${CONFIGURE_FLAGS}
make -j ${NUM_CPUS} libsqlite3.a
make install-lib DESTDIR=${ROOT}/out
diff --git a/src/verify_distribution.py b/src/verify_distribution.py
index 1ac2381..d516f3a 100644
--- a/src/verify_distribution.py
+++ b/src/verify_distribution.py
@@ -122,6 +122,15 @@ def test_sqlite(self):
self.assertTrue(hasattr(conn, "enable_load_extension"))
# Backup feature requires modern SQLite, which we always have.
self.assertTrue(hasattr(conn, "backup"))
+ # Ensure that various extensions are present. These will raise
+ # if they are not.
+ cursor = conn.cursor()
+ cursor.execute("CREATE VIRTUAL TABLE fts3 USING fts3(sender, title, body);")
+ cursor.execute("CREATE VIRTUAL TABLE fts4 USING fts4(sender, title, body);")
+ cursor.execute("CREATE VIRTUAL TABLE fts5 USING fts5(sender, title, body);")
+ cursor.execute("CREATE VIRTUAL TABLE geopoly USING geopoly();")
+ cursor.execute("CREATE VIRTUAL TABLE rtree USING rtree(id, minX, maxX);")
+ conn.close()
def test_ssl(self):
import ssl
From 69c7662d877e7bc899ad46658662a5320ac3f93a Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Sun, 29 Jun 2025 13:31:54 -0400
Subject: [PATCH 26/72] For non-release CI, upload before validating
This allows downloading and poking at build artifacts that fail validation.
Now the order of tasks for all platforms is the same: build, upload
attestations, upload artifacts, validate. (This was already the order for
macos.)
---
.github/workflows/linux.yml | 52 +++++++++++++++++------------------
.github/workflows/windows.yml | 12 ++++----
2 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index d4602fb..39bc873 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -249,6 +249,19 @@ jobs:
./build-linux.py --target-triple ${{ matrix.target_triple }} --python cpython-${{ matrix.python }} --options ${{ matrix.build_options }}
+ - name: Generate attestations
+ uses: actions/attest-build-provenance@v2
+ if: ${{ github.ref == 'refs/heads/main' }}
+ with:
+ subject-path: dist/*
+
+ - name: Upload Distribution
+ if: ${{ ! matrix.dry-run }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }}
+ path: dist/*
+
- name: Validate Distribution
if: ${{ ! matrix.dry-run }}
run: |
@@ -267,19 +280,6 @@ jobs:
build/pythonbuild validate-distribution ${EXTRA_ARGS} dist/*.tar.zst
- - name: Generate attestations
- uses: actions/attest-build-provenance@v2
- if: ${{ github.ref == 'refs/heads/main' }}
- with:
- subject-path: dist/*
-
- - name: Upload Distribution
- if: ${{ ! matrix.dry-run }}
- uses: actions/upload-artifact@v4
- with:
- name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }}
- path: dist/*
-
build-1:
needs:
- generate-matrix
@@ -349,6 +349,19 @@ jobs:
./build-linux.py --target-triple ${{ matrix.target_triple }} --python cpython-${{ matrix.python }} --options ${{ matrix.build_options }}
+ - name: Generate attestations
+ uses: actions/attest-build-provenance@v2
+ if: ${{ github.ref == 'refs/heads/main' }}
+ with:
+ subject-path: dist/*
+
+ - name: Upload Distribution
+ if: ${{ ! matrix.dry-run }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }}
+ path: dist/*
+
- name: Validate Distribution
if: ${{ ! matrix.dry-run }}
run: |
@@ -366,16 +379,3 @@ jobs:
fi
build/pythonbuild validate-distribution ${EXTRA_ARGS} dist/*.tar.zst
-
- - name: Generate attestations
- uses: actions/attest-build-provenance@v2
- if: ${{ github.ref == 'refs/heads/main' }}
- with:
- subject-path: dist/*
-
- - name: Upload Distribution
- if: ${{ ! matrix.dry-run }}
- uses: actions/upload-artifact@v4
- with:
- name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }}
- path: dist/*
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index e285fac..165ff26 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -146,12 +146,6 @@ jobs:
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\${{ matrix.vcvars }}"
py.exe -3.12 build-windows.py --python cpython-${{ matrix.python }} --sh c:\cygwin\bin\sh.exe --options ${{ matrix.build_options }}
- - name: Validate Distribution
- if: ${{ ! matrix.dry-run }}
- run: |
- $Dists = Resolve-Path -Path "dist/*.tar.zst" -Relative
- .\pythonbuild.exe validate-distribution --run $Dists
-
- name: Generate attestations
uses: actions/attest-build-provenance@v2
if: ${{ github.ref == 'refs/heads/main' }}
@@ -163,3 +157,9 @@ jobs:
with:
name: cpython-${{ matrix.python }}-${{ matrix.vcvars }}-${{ matrix.build_options }}
path: dist/*
+
+ - name: Validate Distribution
+ if: ${{ ! matrix.dry-run }}
+ run: |
+ $Dists = Resolve-Path -Path "dist/*.tar.zst" -Relative
+ .\pythonbuild.exe validate-distribution --run $Dists
From 6fd593c4b55c3e5e7dc3831bf97b8538aad8a815 Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Fri, 11 Jul 2025 12:39:06 -0400
Subject: [PATCH 27/72] Skip sqlite3 geopoly test on Windows
---
src/verify_distribution.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/verify_distribution.py b/src/verify_distribution.py
index d516f3a..9773471 100644
--- a/src/verify_distribution.py
+++ b/src/verify_distribution.py
@@ -128,8 +128,12 @@ def test_sqlite(self):
cursor.execute("CREATE VIRTUAL TABLE fts3 USING fts3(sender, title, body);")
cursor.execute("CREATE VIRTUAL TABLE fts4 USING fts4(sender, title, body);")
cursor.execute("CREATE VIRTUAL TABLE fts5 USING fts5(sender, title, body);")
- cursor.execute("CREATE VIRTUAL TABLE geopoly USING geopoly();")
cursor.execute("CREATE VIRTUAL TABLE rtree USING rtree(id, minX, maxX);")
+ if os.name != "nt":
+ # TODO(geofft): not sure why this isn't present in the prebuilt
+ # sqlite3 Windows library from CPython upstream, it seems weird to
+ # be inconsistent across platforms, but that's the status quo
+ cursor.execute("CREATE VIRTUAL TABLE geopoly USING geopoly();")
conn.close()
def test_ssl(self):
From ffffa3d94592dda8a10fd59bbbbf5e1576d6558b Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Fri, 11 Jul 2025 16:12:21 -0400
Subject: [PATCH 28/72] Further fix sqlite test cases (#701)
---
src/verify_distribution.py | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/src/verify_distribution.py b/src/verify_distribution.py
index 9773471..65cd084 100644
--- a/src/verify_distribution.py
+++ b/src/verify_distribution.py
@@ -122,18 +122,21 @@ def test_sqlite(self):
self.assertTrue(hasattr(conn, "enable_load_extension"))
# Backup feature requires modern SQLite, which we always have.
self.assertTrue(hasattr(conn, "backup"))
- # Ensure that various extensions are present. These will raise
- # if they are not.
- cursor = conn.cursor()
- cursor.execute("CREATE VIRTUAL TABLE fts3 USING fts3(sender, title, body);")
- cursor.execute("CREATE VIRTUAL TABLE fts4 USING fts4(sender, title, body);")
- cursor.execute("CREATE VIRTUAL TABLE fts5 USING fts5(sender, title, body);")
- cursor.execute("CREATE VIRTUAL TABLE rtree USING rtree(id, minX, maxX);")
+ # Ensure that various extensions are present. These will raise if they are not. Note that
+ # CPython upstream carries configuration flags for the Windows build, so geopoly is missing
+ # on all versions and rtree is missing in 3.9. On non-Windows platforms, we configure
+ # SQLite ourselves. We might want to patch the build to enable these on Windows, see #666.
+ extensions = ["fts3", "fts4", "fts5"]
if os.name != "nt":
- # TODO(geofft): not sure why this isn't present in the prebuilt
- # sqlite3 Windows library from CPython upstream, it seems weird to
- # be inconsistent across platforms, but that's the status quo
- cursor.execute("CREATE VIRTUAL TABLE geopoly USING geopoly();")
+ extensions.append("geopoly")
+ if os.name == "nt" and sys.version_info[0:2] >= (3, 9):
+ extensions.append("rtree")
+ cursor = conn.cursor()
+ for extension in extensions:
+ with self.subTest(extension=extension):
+ cursor.execute(
+ f"CREATE VIRTUAL TABLE test{extension} USING {extension}(a, b, c);"
+ )
conn.close()
def test_ssl(self):
From 6857d7f7c20b89f02b5581caf778b047f5f4be41 Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Fri, 11 Jul 2025 16:17:11 -0400
Subject: [PATCH 29/72] typo (#702)
---
src/verify_distribution.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/verify_distribution.py b/src/verify_distribution.py
index 65cd084..9dc2740 100644
--- a/src/verify_distribution.py
+++ b/src/verify_distribution.py
@@ -129,7 +129,7 @@ def test_sqlite(self):
extensions = ["fts3", "fts4", "fts5"]
if os.name != "nt":
extensions.append("geopoly")
- if os.name == "nt" and sys.version_info[0:2] >= (3, 9):
+ if os.name != "nt" or sys.version_info[0:2] >= (3, 9):
extensions.append("rtree")
cursor = conn.cursor()
for extension in extensions:
From 684cb94f5c4dd22e1591832532c041110b7f6f90 Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Fri, 11 Jul 2025 18:20:15 -0400
Subject: [PATCH 30/72] typo (#703)
---
src/verify_distribution.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/verify_distribution.py b/src/verify_distribution.py
index 9dc2740..d6e428d 100644
--- a/src/verify_distribution.py
+++ b/src/verify_distribution.py
@@ -129,7 +129,7 @@ def test_sqlite(self):
extensions = ["fts3", "fts4", "fts5"]
if os.name != "nt":
extensions.append("geopoly")
- if os.name != "nt" or sys.version_info[0:2] >= (3, 9):
+ if os.name != "nt" or sys.version_info[0:2] > (3, 9):
extensions.append("rtree")
cursor = conn.cursor()
for extension in extensions:
From 174daa6f039587d2e9488eeccc8d0d7e4573e45a Mon Sep 17 00:00:00 2001
From: Simon Lamon <32477463+silamon@users.noreply.github.com>
Date: Tue, 22 Jul 2025 02:11:47 +0200
Subject: [PATCH 31/72] Update rust dependencies (octocrab & object) (#705)
There are some dependencies with breaking or deprecated changes.
These have been upgraded in this PR applying the breaking changes.
It should unlock
https://github.com/astral-sh/python-build-standalone/pull/633
---
Cargo.lock | 188 +++++++++++++++++-----------------------------
Cargo.toml | 4 +-
src/github.rs | 4 +-
src/validation.rs | 2 +-
4 files changed, 72 insertions(+), 126 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index b0db167..dcb95c7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -263,8 +263,10 @@ checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
dependencies = [
"android-tzdata",
"iana-time-zone",
+ "js-sys",
"num-traits",
"serde",
+ "wasm-bindgen",
"windows-targets",
]
@@ -327,6 +329,16 @@ dependencies = [
"libc",
]
+[[package]]
+name = "core-foundation"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
@@ -395,17 +407,6 @@ dependencies = [
"powerfmt",
]
-[[package]]
-name = "derive_more"
-version = "0.99.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "digest"
version = "0.10.7"
@@ -782,25 +783,6 @@ dependencies = [
"want",
]
-[[package]]
-name = "hyper-rustls"
-version = "0.26.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c"
-dependencies = [
- "futures-util",
- "http",
- "hyper",
- "hyper-util",
- "log",
- "rustls 0.22.4",
- "rustls-native-certs",
- "rustls-pki-types",
- "tokio",
- "tokio-rustls 0.25.0",
- "tower-service",
-]
-
[[package]]
name = "hyper-rustls"
version = "0.27.5"
@@ -811,10 +793,12 @@ dependencies = [
"http",
"hyper",
"hyper-util",
- "rustls 0.23.22",
+ "log",
+ "rustls",
+ "rustls-native-certs",
"rustls-pki-types",
"tokio",
- "tokio-rustls 0.26.1",
+ "tokio-rustls",
"tower-service",
"webpki-roots",
]
@@ -1217,7 +1201,7 @@ dependencies = [
"openssl-probe",
"openssl-sys",
"schannel",
- "security-framework",
+ "security-framework 2.11.1",
"security-framework-sys",
"tempfile",
]
@@ -1264,29 +1248,29 @@ dependencies = [
[[package]]
name = "object"
-version = "0.32.2"
+version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
+checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
- "flate2",
"memchr",
- "ruzstd",
]
[[package]]
name = "object"
-version = "0.36.7"
+version = "0.37.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
+checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a"
dependencies = [
+ "flate2",
"memchr",
+ "ruzstd",
]
[[package]]
name = "octocrab"
-version = "0.34.3"
+version = "0.44.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c4e00a4268539fda6c431a0fd01d016d4b44c361f9c283d0eb8f1ab7408a517"
+checksum = "86996964f8b721067b6ed238aa0ccee56ecad6ee5e714468aa567992d05d2b91"
dependencies = [
"arc-swap",
"async-trait",
@@ -1302,7 +1286,7 @@ dependencies = [
"http-body",
"http-body-util",
"hyper",
- "hyper-rustls 0.26.0",
+ "hyper-rustls",
"hyper-timeout",
"hyper-util",
"jsonwebtoken",
@@ -1316,10 +1300,11 @@ dependencies = [
"serde_urlencoded",
"snafu",
"tokio",
- "tower 0.4.13",
+ "tower",
"tower-http",
"tracing",
"url",
+ "web-time",
]
[[package]]
@@ -1567,7 +1552,7 @@ dependencies = [
"hyper",
"hyper-util",
"normalize-path",
- "object 0.32.2",
+ "object 0.37.1",
"octocrab",
"once_cell",
"pdb",
@@ -1611,7 +1596,7 @@ dependencies = [
"quinn-proto",
"quinn-udp",
"rustc-hash",
- "rustls 0.23.22",
+ "rustls",
"socket2",
"thiserror 2.0.11",
"tokio",
@@ -1629,7 +1614,7 @@ dependencies = [
"rand",
"ring",
"rustc-hash",
- "rustls 0.23.22",
+ "rustls",
"rustls-pki-types",
"slab",
"thiserror 2.0.11",
@@ -1745,7 +1730,7 @@ dependencies = [
"http-body",
"http-body-util",
"hyper",
- "hyper-rustls 0.27.5",
+ "hyper-rustls",
"hyper-tls",
"hyper-util",
"ipnet",
@@ -1757,7 +1742,7 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"quinn",
- "rustls 0.23.22",
+ "rustls",
"rustls-pemfile",
"rustls-pki-types",
"serde",
@@ -1767,9 +1752,9 @@ dependencies = [
"system-configuration",
"tokio",
"tokio-native-tls",
- "tokio-rustls 0.26.1",
+ "tokio-rustls",
"tokio-util",
- "tower 0.5.2",
+ "tower",
"tower-service",
"url",
"wasm-bindgen",
@@ -1865,26 +1850,13 @@ dependencies = [
"windows-sys 0.59.0",
]
-[[package]]
-name = "rustls"
-version = "0.22.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
-dependencies = [
- "log",
- "ring",
- "rustls-pki-types",
- "rustls-webpki",
- "subtle",
- "zeroize",
-]
-
[[package]]
name = "rustls"
version = "0.23.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7"
dependencies = [
+ "log",
"once_cell",
"ring",
"rustls-pki-types",
@@ -1895,15 +1867,14 @@ dependencies = [
[[package]]
name = "rustls-native-certs"
-version = "0.7.3"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5"
+checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3"
dependencies = [
"openssl-probe",
- "rustls-pemfile",
"rustls-pki-types",
"schannel",
- "security-framework",
+ "security-framework 3.2.0",
]
[[package]]
@@ -1943,12 +1914,10 @@ checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
[[package]]
name = "ruzstd"
-version = "0.5.0"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d"
+checksum = "3640bec8aad418d7d03c72ea2de10d5c646a598f9883c7babc160d91e3c1b26c"
dependencies = [
- "byteorder",
- "derive_more",
"twox-hash",
]
@@ -2001,9 +1970,9 @@ dependencies = [
[[package]]
name = "secrecy"
-version = "0.8.0"
+version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e"
+checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a"
dependencies = [
"zeroize",
]
@@ -2015,7 +1984,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.8.0",
- "core-foundation",
+ "core-foundation 0.9.4",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316"
+dependencies = [
+ "bitflags 2.8.0",
+ "core-foundation 0.10.1",
"core-foundation-sys",
"libc",
"security-framework-sys",
@@ -2206,12 +2188,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
-[[package]]
-name = "static_assertions"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
-
[[package]]
name = "strsim"
version = "0.11.1"
@@ -2262,7 +2238,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
dependencies = [
"bitflags 2.8.0",
- "core-foundation",
+ "core-foundation 0.9.4",
"system-configuration-sys",
]
@@ -2433,24 +2409,13 @@ dependencies = [
"tokio",
]
-[[package]]
-name = "tokio-rustls"
-version = "0.25.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
-dependencies = [
- "rustls 0.22.4",
- "rustls-pki-types",
- "tokio",
-]
-
[[package]]
name = "tokio-rustls"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37"
dependencies = [
- "rustls 0.23.22",
+ "rustls",
"tokio",
]
@@ -2467,23 +2432,6 @@ dependencies = [
"tokio",
]
-[[package]]
-name = "tower"
-version = "0.4.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
-dependencies = [
- "futures-core",
- "futures-util",
- "pin-project",
- "pin-project-lite",
- "tokio",
- "tokio-util",
- "tower-layer",
- "tower-service",
- "tracing",
-]
-
[[package]]
name = "tower"
version = "0.5.2"
@@ -2495,25 +2443,26 @@ dependencies = [
"pin-project-lite",
"sync_wrapper",
"tokio",
+ "tokio-util",
"tower-layer",
"tower-service",
+ "tracing",
]
[[package]]
name = "tower-http"
-version = "0.5.2"
+version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
+checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
dependencies = [
"bitflags 2.8.0",
"bytes",
"futures-util",
"http",
"http-body",
- "http-body-util",
"iri-string",
"pin-project-lite",
- "tower 0.4.13",
+ "tower",
"tower-layer",
"tower-service",
"tracing",
@@ -2571,13 +2520,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "twox-hash"
-version = "1.6.3"
+version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
-dependencies = [
- "cfg-if",
- "static_assertions",
-]
+checksum = "8b907da542cbced5261bd3256de1b3a1bf340a3d37f93425a07362a1d687de56"
[[package]]
name = "typenum"
@@ -2809,6 +2754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
+ "serde",
"wasm-bindgen",
]
diff --git a/Cargo.toml b/Cargo.toml
index 82f0298..9b4af3a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,8 +19,8 @@ http-body-util = "0.1.0"
hyper = { version = "1.2.0", features = ["client"] }
hyper-util = { version = "0.1.3" }
normalize-path = "0.2.1"
-object = "0.32.2"
-octocrab = { version = "0.34.1", features = ["rustls", "stream"] }
+object = "0.37.1"
+octocrab = { version = "0.44.1", features = ["rustls", "stream"] }
once_cell = "1.19.0"
pdb = "0.8.0"
pep440_rs = "0.6.6"
diff --git a/src/github.rs b/src/github.rs
index 2dfbba5..7034200 100644
--- a/src/github.rs
+++ b/src/github.rs
@@ -551,8 +551,8 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<(
let mut stream = client
.repos(organization, repo)
- .releases()
- .stream_asset(shasums_asset.id)
+ .release_assets()
+ .stream(shasums_asset.id.into_inner())
.await?;
let mut asset_bytes = Vec::::new();
diff --git a/src/validation.rs b/src/validation.rs
index 5ab7170..b0ffb53 100644
--- a/src/validation.rs
+++ b/src/validation.rs
@@ -1051,7 +1051,7 @@ fn validate_elf>(
{
let strings = symbols.strings();
- for (symbol_index, symbol) in symbols.iter().enumerate() {
+ for (symbol_index, symbol) in symbols.enumerate() {
let name = String::from_utf8_lossy(symbol.name(endian, strings)?);
// If symbol versions are defined and we're in the .dynsym section, there should
From 50a2c25e1f1cba1c3bc39af31505e0e3ffe68e97 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 21 Jul 2025 19:11:56 -0500
Subject: [PATCH 32/72] Bump the python group across 1 directory with 6 updates
(#708)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps the python group with 6 updates in the / directory:
| Package | From | To |
| --- | --- | --- |
| [certifi](https://github.com/certifi/python-certifi) | `2025.6.15` |
`2025.7.14` |
| [jsonschema](https://github.com/python-jsonschema/jsonschema) |
`4.24.0` | `4.25.0` |
| [pywin32](https://github.com/mhammond/pywin32) | `310` | `311` |
| [mypy](https://github.com/python/mypy) | `1.16.1` | `1.17.0` |
| [ruff](https://github.com/astral-sh/ruff) | `0.12.2` | `0.12.4` |
| [types-jsonschema](https://github.com/typeshed-internal/stub_uploader)
| `4.24.0.20250528` | `4.25.0.20250720` |
Updates `certifi` from 2025.6.15 to 2025.7.14
Commits
Updates `jsonschema` from 4.24.0 to 4.25.0
Release notes
Sourced from jsonschema's
releases.
v4.25.0
What's Changed
New Contributors
Full Changelog: https://github.com/python-jsonschema/jsonschema/compare/v4.24.1...v4.25.0
v4.24.1
What's Changed
New Contributors
Full Changelog: https://github.com/python-jsonschema/jsonschema/compare/v4.24.0...v4.24.1
Changelog
Sourced from jsonschema's
changelog.
v4.25.0
- Add support for the
iri and iri-reference
formats to the format-nongpl extra via the MIT-licensed
rfc3987-syntax.
They were alread supported by the format extra. (#1388).
v4.24.1
- Properly escape segments in
ValidationError.json_path
(#139).
Commits
9889f69
Add the new functionality to the CHANGELOG.
18855d0
Merge pull request #1388
from jkowalleck/feat/validate_rfc3987_non-gpl/rfc398...
1a6067f
adjust rfc3987-syntax min-version
6aadb8b
Add the fix to the CHANGELOG.
785741e
Add a dependency group for our new test dependency.
dc54734
Add a uv.lock.
b5572c9
Merge pull request #1390
from kurtmckee/fix-json_path-str-rendering
4cf45b9
Feedback: Use jsonpath-ng to re-parse the rendered JSON path
2680f6a
Feedback: Make a compiled regex pattern private
9a957d7
Unambiguously quote and escape properties in JSON path rendering
- Additional commits viewable in compare
view
Updates `pywin32` from 310 to 311
Release notes
Sourced from pywin32's
releases.
Build 311
A release with a
number of incremental improvements
Install via pip:
pip install pywin32 --upgrade
More details in
the README
Changelog
Sourced from pywin32's
changelog.
Build 311, released 2025/07/14
- Fix use-after-free in CertDeleteCertificateFromStore (#2637)
- Better support for COM identifiers with non-ascii characters (#2632)
- pywin32's own warnings will now refer to the caller, rather than to
the internal source of warning itself (#2594,
@Avasam)
- Fixed a regression that broke special dunder
methods with CoClass. (#1870,
#2493,
@Avasam, @geppi)
- Fixed
TypeError: cannot unpack non-iterable NoneType
object when registering an axscript client ScriptItem (#2513,
@Avasam)
- Fixed a memory leak when SafeArrays are used as out parameters (
@the-snork)
- Fixed dispatch handling for properties (
@the-snork)
- Resolved a handful of deprecation warnings (#2567,
#2576,
@Avasam)
- The following classes now produce a valid
eval string
representation when calling repr: (#2573,
@Avasam)
pywin.tools.browser.HLIPythonObject
win32com.server.exception.COMException
win32comext.axscript.client.error.AXScriptException
win32comext.axscript.client.pyscript.NamedScriptAttribute
- Added initial
DECIMAL/VT_DECIMAL support (#1501,
@gesslerpd)
Commits
Updates `mypy` from 1.16.1 to 1.17.0
Changelog
Sourced from mypy's
changelog.
Mypy Release Notes
Next Release
Mypy 1.17
We’ve just uploaded mypy 1.17 to the Python Package Index (PyPI).
Mypy is a static type checker for Python. This release includes new
features and bug fixes.
You can install it as follows:
python3 -m pip install -U mypy
You can read the full documentation for this release on Read the Docs.
Optionally Check That Match Is Exhaustive
Mypy can now optionally generate an error if a match statement does
not
match exhaustively, without having to use
assert_never(...). Enable
this by using --enable-error-code exhaustive-match.
Example:
# mypy: enable-error-code=exhaustive-match
import enum
class Color(enum.Enum):
RED = 1
BLUE = 2
def show_color(val: Color) -> None:
# error: Unhandled case for values of type
"Literal[Color.BLUE]"
match val:
case Color.RED:
print("red")
This feature was contributed by Donal Burns (PR 19144).
Further Improvements to Attribute Resolution
This release includes additional improvements to how attribute types
and kinds are resolved. These fix many bugs and overall improve
consistency.
- Handle corner case: protocol/class variable/descriptor (Ivan
Levkivskyi, PR 19277)
- Fix a few inconsistencies in protocol/type object interactions (Ivan
Levkivskyi, PR 19267)
- Refactor/unify access to static attributes (Ivan Levkivskyi, PR 19254)
- Remove inconsistencies in operator handling (Ivan Levkivskyi, PR 19250)
- Make protocol subtyping more consistent (Ivan Levkivskyi, PR 18943)
... (truncated)
Commits
0260991
Update version string
3901aa2
Updates to 1.17 changelog (#19436)
7d13396
Initial changelog for 1.17 release (#19427)
a182dec
Combine the revealed types of multiple iteration steps in a more robust
manne...
ab4fd57
Improve the handling of "iteration dependent" errors and notes
in finally cla...
09ba1f6
[mypyc] Fix exception swallowing in async try/finally blocks with await
(#19353)
5c65e33
[mypyc] Fix AttributeError in async try/finally with mixed return paths
(#19361)
934ec50
Lessen dmypy suggest path limitations for Windows machines (#19337)
a4801f9
Type ignore comments erroneously marked as unused by dmypy (#15043)
c3bfa0d
Handle corner case: protocol vs classvar vs descriptor (#19277)
- Additional commits viewable in compare
view
Updates `ruff` from 0.12.2 to 0.12.4
Release notes
Sourced from ruff's
releases.
0.12.4
Release Notes
Preview features
- [
flake8-type-checking, pyupgrade,
ruff] Add from __future__ import annotations
when it would allow new fixes (TC001, TC002,
TC003, UP037, RUF013) (#19100)
- [
flake8-use-pathlib] Add autofix for
PTH109 (#19245)
- [
pylint] Detect indirect pathlib.Path
usages for unspecified-encoding (PLW1514) (#19304)
Bug fixes
- [
flake8-bugbear] Fix B017 false negatives
for keyword exception arguments (#19217)
- [
flake8-use-pathlib] Fix false negative on direct
Path() instantiation (PTH210) (#19388)
- [
flake8-django] Fix DJ008 false positive
for abstract models with type-annotated abstract field (#19221)
- [
isort] Fix I002 import insertion after
docstring with multiple string statements (#19222)
- [
isort] Treat form feed as valid whitespace before a
semicolon (#19343)
- [
pydoclint] Fix SyntaxError from fixes
with line continuations (D201, D202) (#19246)
- [
refurb] FURB164 fix should validate
arguments and should usually be marked unsafe (#19136)
Rule changes
- [
flake8-use-pathlib] Skip single dots for
invalid-pathlib-with-suffix (PTH210) on
versions >= 3.14 (#19331)
- [
pep8_naming] Avoid false positives on standard library
functions with uppercase names (N802) (#18907)
- [
pycodestyle] Handle brace escapes for t-strings in
logical lines (#19358)
- [
pylint] Extend invalid string character rules to
include t-strings (#19355)
- [
ruff] Allow strict kwarg when checking
for starmap-zip (RUF058) in Python 3.14+ (#19333)
Documentation
Contributors
... (truncated)
Changelog
Sourced from ruff's
changelog.
0.12.4
Preview features
- [
flake8-type-checking, pyupgrade,
ruff] Add from __future__ import annotations
when it would allow new fixes (TC001, TC002,
TC003, UP037, RUF013) (#19100)
- [
flake8-use-pathlib] Add autofix for
PTH109 (#19245)
- [
pylint] Detect indirect pathlib.Path
usages for unspecified-encoding (PLW1514) (#19304)
Bug fixes
- [
flake8-bugbear] Fix B017 false negatives
for keyword exception arguments (#19217)
- [
flake8-use-pathlib] Fix false negative on direct
Path() instantiation (PTH210) (#19388)
- [
flake8-django] Fix DJ008 false positive
for abstract models with type-annotated abstract field (#19221)
- [
isort] Fix I002 import insertion after
docstring with multiple string statements (#19222)
- [
isort] Treat form feed as valid whitespace before a
semicolon (#19343)
- [
pydoclint] Fix SyntaxError from fixes
with line continuations (D201, D202) (#19246)
- [
refurb] FURB164 fix should validate
arguments and should usually be marked unsafe (#19136)
Rule changes
- [
flake8-use-pathlib] Skip single dots for
invalid-pathlib-with-suffix (PTH210) on
versions >= 3.14 (#19331)
- [
pep8_naming] Avoid false positives on standard library
functions with uppercase names (N802) (#18907)
- [
pycodestyle] Handle brace escapes for t-strings in
logical lines (#19358)
- [
pylint] Extend invalid string character rules to
include t-strings (#19355)
- [
ruff] Allow strict kwarg when checking
for starmap-zip (RUF058) in Python 3.14+ (#19333)
Documentation
0.12.3
Preview features
- [
flake8-bugbear] Support non-context-manager calls in
B017 (#19063)
- [
flake8-use-pathlib] Add autofixes for
PTH100, PTH106, PTH107,
PTH108, PTH110, PTH111,
PTH112, PTH113, PTH114,
PTH115, PTH117, PTH119,
PTH120 (#19213)
- [
flake8-use-pathlib] Add autofixes for
PTH203, PTH204, PTH205 (#18922)
Bug fixes
- [
flake8-return] Fix false-positive for variables used
inside nested functions in RET504 (#18433)
- Treat form feed as valid whitespace before a line continuation (#19220)
- [
flake8-type-checking] Fix syntax error introduced by
fix (TC008) (#19150)
- [
pyupgrade] Keyword arguments in super
should suppress the UP008 fix (#19131)
Documentation
- [
flake8-pyi] Make example error out-of-the-box
(PYI007, PYI008) (#19103)
- [
flake8-simplify] Make example error out-of-the-box
(SIM116) (#19111)
... (truncated)
Commits
ee2759b
Bump 0.12.4 (#19406)
35f33d9
[ty] publish settings diagnostics (#19335)
5d78b31
[flake8-use-pathlib] Add autofix for PTH109
(#19245)
c2a05b4
[ty] Use bitflags for resolved client capabilities (#19393)
fae0b5c
[ty] Initial implementation of declaration and definition providers. (#19371)
cbe94b0
[ty] Support empty function bodies in if TYPE_CHECKING
blocks (#19372)
029de78
[flake8-use-pathlib] Fix false negative on direct
Path() instantiation (`...
ff94fe7
Treat form feed as valid whitespace before a semicolon (#19343)
b2501b4
[pylint] Detect indirect pathlib.Path usages
for unspecified-encoding (...
291699b
[refurb] FURB164 fix should validate arguments
and should usually be mark...
- Additional commits viewable in compare
view
Updates `types-jsonschema` from 4.24.0.20250528 to 4.25.0.20250720
Commits
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore ` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore ` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore ` will
remove the ignore condition of the specified dependency and ignore
conditions
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
requirements.dev.txt | 110 +++++++++++++++++++++----------------------
requirements.win.txt | 50 +++++++++++---------
2 files changed, 82 insertions(+), 78 deletions(-)
diff --git a/requirements.dev.txt b/requirements.dev.txt
index 0876769..b45edbc 100644
--- a/requirements.dev.txt
+++ b/requirements.dev.txt
@@ -198,39 +198,39 @@ markupsafe==3.0.2 \
# via
# -r requirements.txt
# jinja2
-mypy==1.16.1 \
- --hash=sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359 \
- --hash=sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507 \
- --hash=sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c \
- --hash=sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f \
- --hash=sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15 \
- --hash=sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6 \
- --hash=sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383 \
- --hash=sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b \
- --hash=sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6 \
- --hash=sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca \
- --hash=sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4 \
- --hash=sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574 \
- --hash=sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79 \
- --hash=sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc \
- --hash=sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee \
- --hash=sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40 \
- --hash=sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da \
- --hash=sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37 \
- --hash=sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9 \
- --hash=sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab \
- --hash=sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069 \
- --hash=sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72 \
- --hash=sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536 \
- --hash=sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d \
- --hash=sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a \
- --hash=sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be \
- --hash=sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438 \
- --hash=sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd \
- --hash=sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782 \
- --hash=sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea \
- --hash=sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b \
- --hash=sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d
+mypy==1.17.0 \
+ --hash=sha256:037bc0f0b124ce46bfde955c647f3e395c6174476a968c0f22c95a8d2f589bba \
+ --hash=sha256:03ba330b76710f83d6ac500053f7727270b6b8553b0423348ffb3af6f2f7b889 \
+ --hash=sha256:0e69db1fb65b3114f98c753e3930a00514f5b68794ba80590eb02090d54a5d4a \
+ --hash=sha256:1051df7ec0886fa246a530ae917c473491e9a0ba6938cfd0ec2abc1076495c3e \
+ --hash=sha256:15d9d0018237ab058e5de3d8fce61b6fa72cc59cc78fd91f1b474bce12abf496 \
+ --hash=sha256:1619a485fd0e9c959b943c7b519ed26b712de3002d7de43154a489a2d0fd817d \
+ --hash=sha256:24cfcc1179c4447854e9e406d3af0f77736d631ec87d31c6281ecd5025df625d \
+ --hash=sha256:2c41aa59211e49d717d92b3bb1238c06d387c9325d3122085113c79118bebb06 \
+ --hash=sha256:3204d773bab5ff4ebbd1f8efa11b498027cd57017c003ae970f310e5b96be8d8 \
+ --hash=sha256:3c56f180ff6430e6373db7a1d569317675b0a451caf5fef6ce4ab365f5f2f6c3 \
+ --hash=sha256:434ad499ad8dde8b2f6391ddfa982f41cb07ccda8e3c67781b1bfd4e5f9450a8 \
+ --hash=sha256:51e455a54d199dd6e931cd7ea987d061c2afbaf0960f7f66deef47c90d1b304d \
+ --hash=sha256:63e751f1b5ab51d6f3d219fe3a2fe4523eaa387d854ad06906c63883fde5b1ab \
+ --hash=sha256:6ff25d151cc057fdddb1cb1881ef36e9c41fa2a5e78d8dd71bee6e4dcd2bc05b \
+ --hash=sha256:73a0ff2dd10337ceb521c080d4147755ee302dcde6e1a913babd59473904615f \
+ --hash=sha256:93468cf29aa9a132bceb103bd8475f78cacde2b1b9a94fd978d50d4bdf616c9a \
+ --hash=sha256:98189382b310f16343151f65dd7e6867386d3e35f7878c45cfa11383d175d91f \
+ --hash=sha256:9d4fe5c72fd262d9c2c91c1117d16aac555e05f5beb2bae6a755274c6eec42be \
+ --hash=sha256:b72c34ce05ac3a1361ae2ebb50757fb6e3624032d91488d93544e9f82db0ed6c \
+ --hash=sha256:ba06254a5a22729853209550d80f94e28690d5530c661f9416a68ac097b13fc4 \
+ --hash=sha256:c004135a300ab06a045c1c0d8e3f10215e71d7b4f5bb9a42ab80236364429937 \
+ --hash=sha256:c38876106cb6132259683632b287238858bd58de267d80defb6f418e9ee50658 \
+ --hash=sha256:ce4a17920ec144647d448fc43725b5873548b1aae6c603225626747ededf582d \
+ --hash=sha256:d30ba01c0f151998f367506fab31c2ac4527e6a7b2690107c7a7f9e3cb419a9c \
+ --hash=sha256:d96b196e5c16f41b4f7736840e8455958e832871990c7ba26bf58175e357ed61 \
+ --hash=sha256:e5d7ccc08ba089c06e2f5629c660388ef1fee708444f1dee0b9203fa031dee03 \
+ --hash=sha256:eafaf8b9252734400f9b77df98b4eee3d2eecab16104680d51341c75702cad70 \
+ --hash=sha256:f105f61a5eff52e137fd73bee32958b2add9d9f0a856f17314018646af838e97 \
+ --hash=sha256:f773c6d14dcc108a5b141b4456b0871df638eb411a89cd1c0c001fc4a9d08fc8 \
+ --hash=sha256:f7fb09d05e0f1c329a36dcd30e27564a3555717cde87301fae4fb542402ddfad \
+ --hash=sha256:f8e08de6138043108b3b18f09d3f817a4783912e48828ab397ecf183135d84d6 \
+ --hash=sha256:f986f1cab8dbec39ba6e0eaa42d4d3ac6686516a5d3dccd64be095db05ebc6bb
# via -r requirements.dev.in
mypy-extensions==1.0.0 \
--hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \
@@ -417,25 +417,25 @@ rpds-py==0.22.3 \
# -r requirements.txt
# jsonschema
# referencing
-ruff==0.12.2 \
- --hash=sha256:093ea2b221df1d2b8e7ad92fc6ffdca40a2cb10d8564477a987b44fd4008a7be \
- --hash=sha256:09e4cf27cc10f96b1708100fa851e0daf21767e9709e1649175355280e0d950e \
- --hash=sha256:2a4a20aeed74671b2def096bdf2eac610c7d8ffcbf4fb0e627c06947a1d7078d \
- --hash=sha256:369ffb69b70cd55b6c3fc453b9492d98aed98062db9fec828cdfd069555f5f1a \
- --hash=sha256:3b8b94317cbc2ae4a2771af641739f933934b03555e51515e6e021c64441532d \
- --hash=sha256:3eb3a6b2db4d6e2c77e682f0b988d4d61aff06860158fdb413118ca133d57922 \
- --hash=sha256:45fc42c3bf1d30d2008023a0a9a0cfb06bf9835b147f11fe0679f21ae86d34b1 \
- --hash=sha256:48d6c6bfb4761df68bc05ae630e24f506755e702d4fb08f08460be778c7ccb12 \
- --hash=sha256:4987b8f4ceadf597c927beee65a5eaf994c6e2b631df963f86d8ad1bdea99342 \
- --hash=sha256:6932323db80484dda89153da3d8e58164d01d6da86857c79f1961934354992da \
- --hash=sha256:6aa7e623a3a11538108f61e859ebf016c4f14a7e6e4eba1980190cacb57714ce \
- --hash=sha256:71a4c550195612f486c9d1f2b045a600aeba851b298c667807ae933478fcef04 \
- --hash=sha256:73448de992d05517170fc37169cbca857dfeaeaa8c2b9be494d7bcb0d36c8f4b \
- --hash=sha256:793d8859445ea47591272021a81391350205a4af65a9392401f418a95dfb75c9 \
- --hash=sha256:8ae64755b22f4ff85e9c52d1f82644abd0b6b6b6deedceb74bd71f35c24044cc \
- --hash=sha256:ce48f675c394c37e958bf229fb5c1e843e20945a6d962cf3ea20b7a107dcd9f4 \
- --hash=sha256:d7b4f55cd6f325cb7621244f19c873c565a08aff5a4ba9c69aa7355f3f7afd3e \
- --hash=sha256:dca8a3b6d6dc9810ed8f328d406516bf4d660c00caeaef36eb831cf4871b0639
+ruff==0.12.4 \
+ --hash=sha256:0618ec4442a83ab545e5b71202a5c0ed7791e8471435b94e655b570a5031a98e \
+ --hash=sha256:0fc426bec2e4e5f4c4f182b9d2ce6a75c85ba9bcdbe5c6f2a74fcb8df437df4b \
+ --hash=sha256:13efa16df6c6eeb7d0f091abae50f58e9522f3843edb40d56ad52a5a4a4b6873 \
+ --hash=sha256:2abc48f3d9667fdc74022380b5c745873499ff827393a636f7a59da1515e7c57 \
+ --hash=sha256:2b2449dc0c138d877d629bea151bee8c0ae3b8e9c43f5fcaafcd0c0d0726b184 \
+ --hash=sha256:478fccdb82ca148a98a9ff43658944f7ab5ec41c3c49d77cd99d44da019371a1 \
+ --hash=sha256:4de27977827893cdfb1211d42d84bc180fceb7b72471104671c59be37041cf93 \
+ --hash=sha256:55c0f4ca9769408d9b9bac530c30d3e66490bd2beb2d3dae3e4128a1f05c7442 \
+ --hash=sha256:56e45bb11f625db55f9b70477062e6a1a04d53628eda7784dce6e0f55fd549eb \
+ --hash=sha256:a7dea966bcb55d4ecc4cc3270bccb6f87a337326c9dcd3c07d5b97000dbff41c \
+ --hash=sha256:a8224cc3722c9ad9044da7f89c4c1ec452aef2cfe3904365025dd2f51daeae0e \
+ --hash=sha256:afcfa3ab5ab5dd0e1c39bf286d829e042a15e966b3726eea79528e2e24d8371a \
+ --hash=sha256:be0593c69df9ad1465e8a2d10e3defd111fdb62dcd5be23ae2c06da77e8fcffb \
+ --hash=sha256:c057ce464b1413c926cdb203a0f858cd52f3e73dcb3270a3318d1630f6395bb3 \
+ --hash=sha256:cb0d261dac457ab939aeb247e804125a5d521b21adf27e721895b0d3f83a0d0a \
+ --hash=sha256:e64b90d1122dc2713330350626b10d60818930819623abbb56535c6466cce045 \
+ --hash=sha256:e9949d01d64fa3672449a51ddb5d7548b33e130240ad418884ee6efa7a229586 \
+ --hash=sha256:fe0b9e9eb23736b453143d72d2ceca5db323963330d5b7859d60d101147d461a
# via -r requirements.dev.in
six==1.17.0 \
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
@@ -481,9 +481,9 @@ types-jinja2==2.11.9 \
--hash=sha256:60a1e21e8296979db32f9374d8a239af4cb541ff66447bb915d8ad398f9c63b2 \
--hash=sha256:dbdc74a40aba7aed520b7e4d89e8f0fe4286518494208b35123bcf084d4b8c81
# via -r requirements.dev.in
-types-jsonschema==4.24.0.20250528 \
- --hash=sha256:6a906b5ff73ac11c8d1e0b6c30a9693e1e4e1ab56c56c932b3a7e081b86d187b \
- --hash=sha256:7e28c64e0ae7980eeb158105b20663fc6a6b8f81d5f86ea6614aa0014417bd1e
+types-jsonschema==4.25.0.20250720 \
+ --hash=sha256:765a3b6144798fe3161fd8cbe570a756ed3e8c0e5adb7c09693eb49faad39dbd \
+ --hash=sha256:7d7897c715310d8bf9ae27a2cedba78bbb09e4cad83ce06d2aa79b73a88941df
# via -r requirements.dev.in
types-markupsafe==1.1.10 \
--hash=sha256:85b3a872683d02aea3a5ac2a8ef590193c344092032f58457287fbf8e06711b1 \
diff --git a/requirements.win.txt b/requirements.win.txt
index faa0135..a9132ab 100644
--- a/requirements.win.txt
+++ b/requirements.win.txt
@@ -6,9 +6,9 @@ attrs==25.3.0 \
# via
# jsonschema
# referencing
-certifi==2025.6.15 \
- --hash=sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057 \
- --hash=sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b
+certifi==2025.7.14 \
+ --hash=sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2 \
+ --hash=sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995
# via requests
charset-normalizer==3.4.2 \
--hash=sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4 \
@@ -116,9 +116,9 @@ jinja2==3.1.6 \
--hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \
--hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67
# via -r requirements.in
-jsonschema==4.24.0 \
- --hash=sha256:0b4e8069eb12aedfa881333004bccaec24ecef5a8a6a4b6df142b2cc9599d196 \
- --hash=sha256:a462455f19f5faf404a7902952b6f0e3ce868f3ee09a359b05eca6673bd8412d
+jsonschema==4.25.0 \
+ --hash=sha256:24c2e8da302de79c8b9382fee3e76b355e44d2a4364bb207159ce10b517bd716 \
+ --hash=sha256:e63acf5c11762c0e6672ffb61482bdf57f0876684d8d249c0fe2d730d48bc55f
# via -r requirements.in
jsonschema-specifications==2025.4.1 \
--hash=sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af \
@@ -187,23 +187,27 @@ markupsafe==3.0.2 \
--hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \
--hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50
# via jinja2
-pywin32==310 \
- --hash=sha256:0867beb8addefa2e3979d4084352e4ac6e991ca45373390775f7084cc0209b9c \
- --hash=sha256:126298077a9d7c95c53823934f000599f66ec9296b09167810eb24875f32689c \
- --hash=sha256:19ec5fc9b1d51c4350be7bb00760ffce46e6c95eaf2f0b2f1150657b1a43c582 \
- --hash=sha256:1e765f9564e83011a63321bb9d27ec456a0ed90d3732c4b2e312b855365ed8bd \
- --hash=sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966 \
- --hash=sha256:30f0a9b3138fb5e07eb4973b7077e1883f558e40c578c6925acc7a94c34eaa36 \
- --hash=sha256:33babed0cf0c92a6f94cc6cc13546ab24ee13e3e800e61ed87609ab91e4c8213 \
- --hash=sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab \
- --hash=sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e \
- --hash=sha256:6dd97011efc8bf51d6793a82292419eba2c71cf8e7250cfac03bba284454abc1 \
- --hash=sha256:851c8d927af0d879221e616ae1f66145253537bbdd321a77e8ef701b443a9a1a \
- --hash=sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d \
- --hash=sha256:96867217335559ac619f00ad70e513c0fcf84b8a3af9fc2bba3b59b97da70475 \
- --hash=sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060 \
- --hash=sha256:c3e78706e4229b915a0821941a84e7ef420bf2b77e08c9dae3c76fd03fd2ae3d \
- --hash=sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33
+pywin32==311 \
+ --hash=sha256:0502d1facf1fed4839a9a51ccbcc63d952cf318f78ffc00a7e78528ac27d7a2b \
+ --hash=sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151 \
+ --hash=sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87 \
+ --hash=sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503 \
+ --hash=sha256:62ea666235135fee79bb154e695f3ff67370afefd71bd7fea7512fc70ef31e3d \
+ --hash=sha256:6c6f2969607b5023b0d9ce2541f8d2cbb01c4f46bc87456017cf63b73f1e2d8c \
+ --hash=sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d \
+ --hash=sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31 \
+ --hash=sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b \
+ --hash=sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a \
+ --hash=sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42 \
+ --hash=sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2 \
+ --hash=sha256:aba8f82d551a942cb20d4a83413ccbac30790b50efb89a75e4f586ac0bb8056b \
+ --hash=sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee \
+ --hash=sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067 \
+ --hash=sha256:c8015b09fb9a5e188f83b7b04de91ddca4658cee2ae6f3bc483f0b21a77ef6cd \
+ --hash=sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3 \
+ --hash=sha256:e0c4cfb0621281fe40387df582097fd796e80430597cb9944f0ae70447bacd91 \
+ --hash=sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852 \
+ --hash=sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d
# via docker
pyyaml==6.0.2 \
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
From cf3c7eaf4e668e064e3260b09e366231075cfc8c Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Mon, 21 Jul 2025 19:18:45 -0500
Subject: [PATCH 33/72] Run dependabot monthly instead of weekly (#709)
The CI is expensive and there is ~no benefit to end users from a faster
update cadence
---
.github/dependabot.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 7a97743..a79e311 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -3,7 +3,7 @@ updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
- interval: "weekly"
+ interval: "monthly"
groups:
python:
patterns:
@@ -11,7 +11,7 @@ updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
- interval: "weekly"
+ interval: "monthly"
groups:
rust:
patterns:
From 0ca55fec9f0f20edf1907f7e2b2824d4b54ea03b Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Tue, 22 Jul 2025 20:12:07 -0400
Subject: [PATCH 34/72] Bump CPython to 3.14.0rc1 (#710)
---
cpython-unix/extension-modules.yml | 3 +++
pythonbuild/downloads.py | 8 ++++----
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/cpython-unix/extension-modules.yml b/cpython-unix/extension-modules.yml
index 4b83456..c069ca1 100644
--- a/cpython-unix/extension-modules.yml
+++ b/cpython-unix/extension-modules.yml
@@ -206,6 +206,9 @@ _curses_panel:
_datetime:
sources:
- _datetimemodule.c
+ setup-enabled-conditional:
+ - enabled: true
+ minimum-python-version: "3.14"
_dbm:
sources:
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index 20d5c98..78a2401 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -82,10 +82,10 @@
"python_tag": "cp313",
},
"cpython-3.14": {
- "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0b4.tar.xz",
- "size": 23641472,
- "sha256": "15e123e056abebba6de5e73cfa304459a8c82cafa85d4fc7fc6de80e6a3e1b39",
- "version": "3.14.0b4",
+ "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0rc1.tar.xz",
+ "size": 23661916,
+ "sha256": "8707780ae9f19c5bf5b9f27827181ba11cdad7bb292ea49cad5424331e40ee8b",
+ "version": "3.14.0rc1",
"licenses": ["Python-2.0", "CNRI-Python"],
"license_file": "LICENSE.cpython.txt",
"python_tag": "cp314",
From 32b1e3038310a9e6333f65fc49d27e164174998c Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Tue, 1 Jul 2025 16:02:59 -0400
Subject: [PATCH 35/72] Allow using a custom GitHub API endpoint for releasing
This lets me test the release scripts against a custom, fault-injected
Python server, but I suppose it might also be useful for downstream
users who have GHES, maybe. Patches welcome if anyone is using this and
it doesn't quite work right!
---
src/github.rs | 30 ++++++++++++++++--------------
src/main.rs | 12 ++++++++++++
2 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/src/github.rs b/src/github.rs
index 7034200..f42d999 100644
--- a/src/github.rs
+++ b/src/github.rs
@@ -112,6 +112,20 @@ async fn upload_release_artifact(
Ok(())
}
+fn new_github_client(args: &ArgMatches) -> Result<(Octocrab, String)> {
+ let token = args
+ .get_one::("token")
+ .expect("token should be specified")
+ .to_string();
+ let github_uri = args.get_one::("github-uri");
+
+ let mut builder = OctocrabBuilder::new().personal_token(token.clone());
+ if let Some(github_uri) = github_uri {
+ builder = builder.base_uri(github_uri.clone())?;
+ }
+ Ok((builder.build()?, token))
+}
+
pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<()> {
let dest_dir = args
.get_one::("dest")
@@ -121,13 +135,7 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<()
.expect("organization should be set");
let repo = args.get_one::("repo").expect("repo should be set");
- let client = OctocrabBuilder::new()
- .personal_token(
- args.get_one::("token")
- .expect("token should be required argument")
- .to_string(),
- )
- .build()?;
+ let (client, _) = new_github_client(args)?;
let release_version_range = pep440_rs::VersionSpecifier::from_str(">=3.9")?;
@@ -358,10 +366,6 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<(
.get_one::("tag")
.expect("tag should be specified");
let ignore_missing = args.get_flag("ignore_missing");
- let token = args
- .get_one::("token")
- .expect("token should be specified")
- .to_string();
let organization = args
.get_one::("organization")
.expect("organization should be specified");
@@ -451,9 +455,7 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<(
return Err(anyhow!("missing {} release artifacts", missing.len()));
}
- let client = OctocrabBuilder::new()
- .personal_token(token.clone())
- .build()?;
+ let (client, token) = new_github_client(args)?;
let repo_handler = client.repos(organization, repo);
let releases = repo_handler.releases();
diff --git a/src/main.rs b/src/main.rs
index df441e1..c8d422e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -70,6 +70,12 @@ fn main_impl() -> Result<()> {
.action(ArgAction::Set)
.default_value("python-build-standalone")
.help("GitHub repository name"),
+ )
+ .arg(
+ Arg::new("github-uri")
+ .long("github-uri")
+ .action(ArgAction::Set)
+ .help("Alternative GitHub URI"),
),
);
@@ -154,6 +160,12 @@ fn main_impl() -> Result<()> {
.action(ArgAction::Set)
.default_value("python-build-standalone")
.help("GitHub repository name"),
+ )
+ .arg(
+ Arg::new("github-uri")
+ .long("github-uri")
+ .action(ArgAction::Set)
+ .help("Alternative GitHub URI"),
),
);
From abac59fdd834e9a84aa2a3a6954232ddce772c66 Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Sun, 29 Jun 2025 16:34:13 -0400
Subject: [PATCH 36/72] Do not load the entire artifact in memory when
uploading (#618)
---
Cargo.lock | 1 +
Cargo.toml | 1 +
src/github.rs | 119 +++++++++-----
src/github_api_tester.py | 340 +++++++++++++++++++++++++++++++++++++++
4 files changed, 424 insertions(+), 37 deletions(-)
create mode 100755 src/github_api_tester.py
diff --git a/Cargo.lock b/Cargo.lock
index dcb95c7..6a2f089 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1570,6 +1570,7 @@ dependencies = [
"tempfile",
"text-stub-library",
"tokio",
+ "tokio-util",
"url",
"version-compare",
"zip",
diff --git a/Cargo.toml b/Cargo.toml
index 9b4af3a..b74eeb6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -37,6 +37,7 @@ tar = "0.4.40"
tempfile = "3.10.0"
text-stub-library = "0.9.0"
tokio = "1.43.1"
+tokio-util = "0.7.13"
url = "2.5.0"
version-compare = "0.1.1"
zip = "0.6.6"
diff --git a/src/github.rs b/src/github.rs
index f42d999..676104f 100644
--- a/src/github.rs
+++ b/src/github.rs
@@ -17,10 +17,9 @@ use {
},
rayon::prelude::*,
reqwest::{Client, StatusCode},
- reqwest_middleware::{self, ClientWithMiddleware},
reqwest_retry::{
- default_on_request_failure, policies::ExponentialBackoff, RetryTransientMiddleware,
- Retryable, RetryableStrategy,
+ default_on_request_failure, policies::ExponentialBackoff, RetryPolicy, Retryable,
+ RetryableStrategy,
},
sha2::{Digest, Sha256},
std::{
@@ -28,6 +27,7 @@ use {
io::Read,
path::PathBuf,
str::FromStr,
+ time::{Duration, SystemTime},
},
url::Url,
zip::ZipArchive,
@@ -65,12 +65,19 @@ async fn fetch_artifact(
Ok(res)
}
+enum UploadSource {
+ Filename(PathBuf),
+ Data(Bytes),
+}
+
async fn upload_release_artifact(
- client: &ClientWithMiddleware,
+ client: &Client,
+ retry_policy: &impl RetryPolicy,
+ retryable_strategy: &impl RetryableStrategy,
auth_token: String,
release: &Release,
filename: String,
- data: Bytes,
+ body: UploadSource,
dry_run: bool,
) -> Result<()> {
if release.assets.iter().any(|asset| asset.name == filename) {
@@ -93,17 +100,52 @@ async fn upload_release_artifact(
return Ok(());
}
- // Octocrab doesn't yet support release artifact upload. And the low-level HTTP API
- // forces the use of strings on us. So we have to make our own HTTP client.
-
- let response = client
- .put(url)
- .header("Authorization", format!("Bearer {auth_token}"))
- .header("Content-Length", data.len())
- .header("Content-Type", "application/x-tar")
- .body(data)
- .send()
- .await?;
+ // Octocrab's high-level API for uploading release artifacts doesn't yet support streaming
+ // bodies, and their low-level API isn't more helpful than using our own HTTP client.
+ //
+ // Because we are streaming the body, we can't use the standard retry middleware for reqwest
+ // (see e.g. https://github.com/seanmonstar/reqwest/issues/2416), so we have to recreate the
+ // request on each retry and handle the retry logic ourself. This logic is inspired by
+ // uv/crates/uv-publish/src/lib.rs (which has the same problem), which in turn is inspired by
+ // reqwest-middleware/reqwest-retry/src/middleware.rs.
+ //
+ // (While Octocrab's API would work fine for the non-streaming case, we just use this function
+ // for both cases so that we can make a homogeneous Vec later in the file.)
+
+ let mut n_past_retries = 0;
+ let start_time = SystemTime::now();
+ let response = loop {
+ let request = client
+ .put(url.clone())
+ .timeout(Duration::from_secs(60))
+ .header("Authorization", format!("Bearer {auth_token}"))
+ .header("Content-Type", "application/octet-stream");
+ let request = match body {
+ UploadSource::Filename(ref path) => {
+ let file = tokio::fs::File::open(&path).await?;
+ let len = file.metadata().await?.len();
+ request.header("Content-Length", len).body(file)
+ }
+ UploadSource::Data(ref bytes) => request
+ .header("Content-Length", bytes.len())
+ .body(bytes.clone()),
+ };
+ let result = request.send().await.map_err(|e| e.into());
+
+ if retryable_strategy.handle(&result) == Some(Retryable::Transient) {
+ let retry_decision = retry_policy.should_retry(start_time, n_past_retries);
+ if let reqwest_retry::RetryDecision::Retry { execute_after } = retry_decision {
+ println!("retrying upload to {url} after {result:?}");
+ let duration = execute_after
+ .duration_since(SystemTime::now())
+ .unwrap_or_else(|_| Duration::default());
+ tokio::time::sleep(duration).await;
+ n_past_retries += 1;
+ continue;
+ }
+ }
+ break result?;
+ };
if !response.status().is_success() {
return Err(anyhow!("HTTP {}", response.status()));
@@ -215,10 +257,8 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<()
.await?;
for artifact in artifacts {
- if matches!(
- artifact.name.as_str(),
- "pythonbuild" | "toolchain"
- ) || artifact.name.contains("install-only")
+ if matches!(artifact.name.as_str(), "pythonbuild" | "toolchain")
+ || artifact.name.contains("install-only")
{
continue;
}
@@ -475,12 +515,7 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<(
let mut digests = BTreeMap::new();
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(5);
- let raw_client = reqwest_middleware::ClientBuilder::new(Client::new())
- .with(RetryTransientMiddleware::new_with_policy_and_strategy(
- retry_policy,
- GitHubUploadRetryStrategy,
- ))
- .build();
+ let raw_client = Client::new();
{
let mut fs = vec![];
@@ -490,23 +525,31 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<(
continue;
}
- let file_data = Bytes::copy_from_slice(&std::fs::read(dist_dir.join(&source))?);
-
- let mut digest = Sha256::new();
- digest.update(&file_data);
-
- let digest = hex::encode(digest.finalize());
-
- digests.insert(dest.clone(), digest.clone());
-
+ let local_filename = dist_dir.join(&source);
fs.push(upload_release_artifact(
&raw_client,
+ &retry_policy,
+ &GitHubUploadRetryStrategy,
token.clone(),
&release,
dest.clone(),
- file_data,
+ UploadSource::Filename(local_filename.clone()),
dry_run,
));
+
+ // reqwest wants to take ownership of the body, so it's hard for us to do anything
+ // clever with reading the file once and calculating the sha256sum while we read.
+ // So we open and read the file again.
+ let digest = {
+ let file = tokio::fs::File::open(local_filename).await?;
+ let mut stream = tokio_util::io::ReaderStream::with_capacity(file, 1048576);
+ let mut hasher = Sha256::new();
+ while let Some(chunk) = stream.next().await {
+ hasher.update(&chunk?);
+ }
+ hex::encode(hasher.finalize())
+ };
+ digests.insert(dest.clone(), digest.clone());
}
let mut buffered = futures::stream::iter(fs).buffer_unordered(16);
@@ -526,10 +569,12 @@ pub async fn command_upload_release_distributions(args: &ArgMatches) -> Result<(
upload_release_artifact(
&raw_client,
+ &retry_policy,
+ &GitHubUploadRetryStrategy,
token.clone(),
&release,
"SHA256SUMS".to_string(),
- Bytes::copy_from_slice(shasums.as_bytes()),
+ UploadSource::Data(Bytes::copy_from_slice(shasums.as_bytes())),
dry_run,
)
.await?;
diff --git a/src/github_api_tester.py b/src/github_api_tester.py
new file mode 100755
index 0000000..9ff4bc0
--- /dev/null
+++ b/src/github_api_tester.py
@@ -0,0 +1,340 @@
+#!/usr/bin/env -S uv run
+#
+# A fake GitHub API server for testing upload-release-distributions's
+# behavior in the presence of API failures.
+#
+# Call with no arguments or with pytest CLI arguments to run the tests
+# at the bottom which invoke `cargo run`.
+#
+# Call with one argument "serve" to start an HTTP server on 0.0.0.0.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# /// script
+# requires-python = ">=3.13"
+# dependencies = [
+# "quart>=0.20.0",
+# "quart-trio>=0.12.0",
+# # Pinned because we mess with hypercorn internals, see below.
+# "hypercorn==0.17.3",
+# "pytest",
+# "pytest-trio",
+# ]
+# ///
+
+import dataclasses
+import hashlib
+import logging
+import os
+import sys
+from collections.abc import Callable
+
+import hypercorn
+import pytest
+import quart
+import trio
+from quart import request
+from quart_trio import QuartTrio
+
+app = QuartTrio(__name__)
+app.config["MAX_CONTENT_LENGTH"] = None
+
+
+async def drop_connection():
+ """Drop the (HTTP/1.1) connection belonging to the current Quart request."""
+ # We need to do two things:
+ # - Convince hypercorn (specifically, around HTTPStream.app_send())
+ # that it doesn't need to send a 500 and can just close the socket.
+ # - Convince h11's state machine that it's okay to close the socket
+ # without sending a response.
+ # We can't do this at the ASGI layer: hypercorn will insert the 500
+ # for protocol compliance if the ASGI app doesn't provide a
+ # response. We need to modify the actual HTTP server, either with a
+ # pull request or by digging into its internals as follows:
+ # - Grab the HTTPStream whose bound method app_send was passed into
+ # the Quart request
+ # - Grab the H11Protocol whose bound method stream_send was passed
+ # into the HTTPStream's constructor
+ # - Tell the H11Protocol's underlying h11 state machine to act as if
+ # the remote side errored, so it thinks dropping the connection is
+ # the appropriate next step and not misbehavior on our end
+ # - Tell the HTTPStream to move the state machine forward with no
+ # further send on our side, which will drop the connection (and
+ # not consider it for keepalive)
+ import hypercorn.protocol as hp
+
+ http_stream: hp.http_stream.HTTPStream = request._send_push_promise.args[0].__self__
+ protocol: hp.h11.H11Protocol = http_stream.send.__self__
+ protocol.connection._process_error(protocol.connection.their_role)
+ await http_stream.send(hp.events.EndBody(stream_id=http_stream.stream_id))
+ await http_stream.app_send(None)
+
+ # Some other things I tried, kept for reference:
+ # http_stream.state = hypercorn.protocol.http_stream.ASGIHTTPState.RESPONSE
+ # await http_stream._send_closed()
+ # http_stream.state = hypercorn.protocol.http_stream.ASGIHTTPState.CLOSED
+
+
+# The following GitHub API datatypes are complete enough to satisfy
+# octocrab's deserialization.
+
+
+@dataclasses.dataclass
+class Asset:
+ name: str
+ label: str | None
+ sha256: str
+ contents: bytes | None
+
+ _ASSETS = []
+
+ def __post_init__(self):
+ self.id = len(self._ASSETS)
+ self._ASSETS.append(self)
+
+ def render(self) -> dict:
+ return {
+ "url": quart.url_for("get_asset", id=self.id, _external=True),
+ "browser_download_url": "https://github.invalid/unneeded",
+ "id": self.id,
+ "node_id": "fakenode",
+ "name": self.name,
+ "label": self.label,
+ "state": "uploaded",
+ "content_type": "application/octet-stream",
+ "size": 1000,
+ "download_count": 1000,
+ "created_at": "2020-01-01T00:00:00Z",
+ "updated_at": "2020-01-01T00:00:00Z",
+ "uploader": None,
+ }
+
+
+@dataclasses.dataclass
+class Upload:
+ name: str
+ label: str | None
+
+ def __post_init__(self):
+ self.hasher = hashlib.sha256()
+ if self.name == "SHA256SUMS":
+ self.contents = b""
+ else:
+ self.contents = None
+
+ def update(self, chunk: bytes) -> None:
+ self.hasher.update(chunk)
+ if self.contents is not None:
+ self.contents += chunk
+
+ def to_asset(self) -> Asset:
+ return Asset(self.name, self.label, self.hasher.hexdigest(), self.contents)
+
+
+@dataclasses.dataclass
+class Release:
+ release_id: int
+ tag_name: str
+ assets: list = dataclasses.field(default_factory=list)
+ # fault0 and fault1 are called before and after receiving the first
+ # chunk of a PUT request, respectively. Each is called once per
+ # release - the first upload that hits it will disarm it.
+ fault0: Callable[[], None] | None = None
+ fault1: Callable[[], None] | None = None
+
+ def render(self) -> dict:
+ upload_asset = quart.url_for(
+ "upload_asset", release=self.release_id, _external=True
+ )
+ return {
+ "url": request.url,
+ "html_url": "https://github.invalid/unneeded",
+ "assets_url": "https://github.invalid/unneeded",
+ "upload_url": upload_asset + "{?name,label}",
+ "id": self.release_id,
+ "node_id": "fakenode",
+ "tag_name": self.tag_name,
+ "target_commitish": "main",
+ "draft": False,
+ "prerelease": True,
+ "assets": [i.render() for i in self.assets],
+ }
+
+
+releases = [
+ Release(1, "basic"),
+ Release(11, "early-drop", fault0=drop_connection),
+ Release(12, "late-drop", fault1=drop_connection),
+ Release(4011, "early-401", fault0=lambda: quart.abort(401)),
+ Release(4012, "late-401", fault1=lambda: quart.abort(401)),
+ Release(4031, "early-403", fault0=lambda: quart.abort(403)),
+ Release(4032, "late-403", fault1=lambda: quart.abort(403)),
+ Release(5001, "early-500", fault0=lambda: quart.abort(500)),
+ Release(5002, "late-500", fault1=lambda: quart.abort(500)),
+]
+
+
+def get_release(*, tag=None, release=None) -> Release:
+ if tag is not None:
+ condition = lambda r: r.tag_name == tag
+ elif release is not None:
+ condition = lambda r: r.release_id == release
+ else:
+ raise TypeError("tag or release must be set")
+
+ for r in releases:
+ if condition(r):
+ return r
+ quart.abort(404, response=quart.jsonify({"message": "Not Found", "status": "404"}))
+
+
+# GitHub API functions
+
+
+@app.route("/repos///releases/tags/")
+async def get_release_by_tag(org, repo, tag):
+ return get_release(tag=tag).render()
+
+
+@app.route("/repos///releases/")
+async def get_release_by_id(org, repo, release):
+ return get_release(release=release).render()
+
+
+@app.put("/upload//assets")
+async def upload_asset(release):
+ filename = request.args["name"]
+ release = get_release(release=release)
+
+ if (fault := release.fault0) is not None:
+ logging.info(f"{filename}: injecting fault0")
+ release.fault0 = None
+ return await fault()
+
+ logging.info(f"{filename}: upload begin")
+ upload = Upload(filename, request.args.get("label"))
+ async for chunk in request.body:
+ logging.debug(f"{filename}: {len(chunk)=}")
+ upload.update(chunk)
+ if (fault := release.fault1) is not None:
+ if "SHA256" not in filename:
+ logging.info(f"{filename}: injecting fault1")
+ release.fault1 = None
+ return await fault()
+
+ asset = upload.to_asset()
+ logging.info(f"{filename}: upload complete, {asset.sha256=}")
+ release.assets.append(asset)
+ return asset.render()
+
+
+@app.route("/get_asset/")
+@app.route("/repos///releases/assets/")
+async def get_asset(id, org=None, repo=None):
+ try:
+ asset = Asset._ASSETS[id]
+ except IndexError:
+ quart.abort(
+ 404, response=quart.jsonify({"message": "Not Found", "status": "404"})
+ )
+
+ if "application/octet-stream" in request.accept_mimetypes:
+ if asset.contents is None:
+ print(
+ f"USAGE ERROR: Received request for contents of {asset.filename=} which was not stored"
+ )
+ return "Did not store contents", 410
+ return asset.contents
+ else:
+ return asset.render()
+
+
+# Generic upload function, useful for testing clients in isolation
+
+
+@app.put("/file/")
+async def upload_file(path):
+ logging.info(f"{path}: upload begin")
+ s = hashlib.sha256()
+ async for chunk in request.body:
+ logging.debug(f"{path}: {len(chunk)=}")
+ if "drop" in request.args:
+ await drop_connection()
+ s.update(chunk)
+ digest = s.hexdigest()
+ logging.info(f"{path}: {digest=}")
+ return f"{digest} {path}\n", 500
+
+
+# Test cases
+
+
+@pytest.fixture
+async def server(nursery):
+ await nursery.start(app.run_task)
+
+
+FILENAME = "cpython-3.0.0-x86_64-unknown-linux-gnu-install_only-19700101T1234.tar.gz"
+SHA256_20MEG = "9e21c61969cd3e077a1b2b58ddb583b175e13c6479d2d83912eaddc23c0cdd52"
+
+
+@pytest.fixture(scope="session")
+def upload_release_distributions(tmp_path_factory):
+ dist = tmp_path_factory.mktemp("dist")
+ filename = dist / FILENAME
+ filename.touch()
+ os.truncate(filename, 20_000_000)
+
+ async def upload_release_distributions(*args):
+ return await trio.run_process(
+ [
+ "cargo",
+ "run",
+ "--",
+ "upload-release-distributions",
+ "--github-uri",
+ "http://localhost:5000",
+ "--token",
+ "no-token-needed",
+ "--dist",
+ dist,
+ "--datetime",
+ "19700101T1234",
+ "--ignore-missing",
+ ]
+ + list(args)
+ )
+
+ return upload_release_distributions
+
+
+# TODO: test all of [r.tag_name for r in releases]
+TAGS_TO_TEST = ["basic", "early-drop", "late-drop", "early-403", "late-403"]
+
+
+@pytest.mark.parametrize("tag", TAGS_TO_TEST)
+async def test_upload(server, upload_release_distributions, tag):
+ with trio.fail_after(300):
+ await upload_release_distributions("--tag", tag)
+ release = get_release(tag=tag)
+ assets = sorted(release.assets, key=lambda a: a.name)
+ assert len(assets) == 2
+ assert assets[0].name == "SHA256SUMS"
+ filename = FILENAME.replace("3.0.0", f"3.0.0+{tag}").replace("-19700101T1234", "")
+ assert assets[1].name == filename
+ assert assets[1].sha256 == SHA256_20MEG
+ assert assets[0].contents == f"{SHA256_20MEG} {filename}\n".encode()
+
+
+# Work around https://github.com/pgjones/hypercorn/issues/238 not being in a release
+# Without it, test failures are unnecessarily noisy
+hypercorn.trio.lifespan.LifespanFailureError = trio.Cancelled
+
+if __name__ == "__main__":
+ if len(sys.argv) > 1 and sys.argv[1] == "serve":
+ logging.basicConfig(level=logging.INFO)
+ app.run("0.0.0.0")
+ else:
+ pytest.main(["-o", "trio_mode=true", __file__] + sys.argv[1:])
From a376f32981a4e690963fe29a6ae31203afb440ae Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Wed, 23 Jul 2025 10:51:58 -0400
Subject: [PATCH 37/72] Go back to the normal runner for the releease process
Now that we're not loading every artifact in memory, hopefully the
normal runner will work.
---
.github/workflows/release.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 6381b3e..a81dc2f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -29,7 +29,7 @@ jobs:
release:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- runs-on: github-ubuntu-24.04-x86_64-16
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
From 98ed87173db339948c7a666937ceed396ec519ec Mon Sep 17 00:00:00 2001
From: William Woodruff
Date: Fri, 1 Aug 2025 10:25:32 -0400
Subject: [PATCH 38/72] chore(ci): apply security fixes, add zizmor workflow
(#716)
---
.github/dependabot.yml | 46 +++++++++++++++++---------
.github/workflows/check.yml | 4 +++
.github/workflows/linux.yml | 62 ++++++++++++++++++++++++++---------
.github/workflows/macos.yml | 38 ++++++++++++++-------
.github/workflows/release.yml | 50 ++++++++++++++++++----------
.github/workflows/windows.yml | 31 +++++++++++++-----
.github/workflows/zizmor.yml | 24 ++++++++++++++
.github/zizmor.yml | 7 ++++
8 files changed, 194 insertions(+), 68 deletions(-)
create mode 100644 .github/workflows/zizmor.yml
create mode 100644 .github/zizmor.yml
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index a79e311..b299420 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,18 +1,32 @@
version: 2
updates:
-- package-ecosystem: "pip"
- directory: "/"
- schedule:
- interval: "monthly"
- groups:
- python:
- patterns:
- - "*"
-- package-ecosystem: "cargo"
- directory: "/"
- schedule:
- interval: "monthly"
- groups:
- rust:
- patterns:
- - "*"
+ - package-ecosystem: "pip"
+ directory: "/"
+ schedule:
+ interval: "monthly"
+ cooldown:
+ default-days: 14
+ groups:
+ python:
+ patterns:
+ - "*"
+ - package-ecosystem: "cargo"
+ directory: "/"
+ schedule:
+ interval: "monthly"
+ cooldown:
+ default-days: 14
+ groups:
+ rust:
+ patterns:
+ - "*"
+ - package-ecosystem: "github-actions"
+ directory: ".github/workflows"
+ schedule:
+ interval: "monthly"
+ cooldown:
+ default-days: 14
+ groups:
+ actions:
+ patterns:
+ - "*"
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 5630ba4..c7874e7 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -12,12 +12,16 @@ concurrency:
env:
FORCE_COLOR: 1
+permissions: {}
+
jobs:
check:
runs-on: "ubuntu-latest"
name: "check"
steps:
- uses: actions/checkout@v4
+ with:
+ persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: "3.12"
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 39bc873..2ed390b 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -2,7 +2,7 @@ name: linux
on:
push:
- branches: [ main ]
+ branches: [main]
pull_request:
concurrency:
@@ -12,6 +12,8 @@ concurrency:
env:
FORCE_COLOR: 1
+permissions: {}
+
jobs:
crate-build:
needs:
@@ -28,6 +30,8 @@ jobs:
sudo apt install -y --no-install-recommends libssl-dev pkg-config
- uses: actions/checkout@v4
+ with:
+ persist-credentials: false
- name: Emit rustc version
run: |
@@ -64,11 +68,13 @@ jobs:
packages: write
steps:
- uses: actions/checkout@v4
+ with:
+ persist-credentials: false
- name: Install Python
uses: actions/setup-python@v5
with:
- python-version: '3.11'
+ python-version: "3.11"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
@@ -90,7 +96,7 @@ jobs:
- name: Build Image
id: build-image
- uses: docker/build-push-action@v5
+ uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
file: build/${{ matrix.name }}.Dockerfile
@@ -110,8 +116,12 @@ jobs:
- name: Compress Image
run: |
- echo ${{ steps.build-image.outputs.imageid }} > build/image-${{ matrix.name }}.linux_${{ matrix.arch }}
+ echo ${STEPS_BUILD_IMAGE_OUTPUTS_IMAGEID} > build/image-${MATRIX_NAME}.linux_${MATRIX_ARCH}
zstd -v -T0 -6 --rm build/image-*.tar
+ env:
+ STEPS_BUILD_IMAGE_OUTPUTS_IMAGEID: ${{ steps.build-image.outputs.imageid }}
+ MATRIX_NAME: ${{ matrix.name }}
+ MATRIX_ARCH: ${{ matrix.arch }}
- name: Upload Docker Image
uses: actions/upload-artifact@v4
@@ -120,6 +130,7 @@ jobs:
path: build/image-*
generate-matrix:
+ name: Generate build matrix
runs-on: ubuntu-latest
outputs:
python-build-matrix-0: ${{ steps.set-matrix.outputs.python-build-matrix-0 }}
@@ -130,16 +141,19 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
- fetch-depth: 0 # fetch history for subsequent `git diff`
+ fetch-depth: 0
+ persist-credentials: false
- name: Set up Python
uses: astral-sh/setup-uv@v4
- name: Get pull request labels
id: get-labels
+ env:
+ PULL_REQUEST_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
# Convert GitHub labels array to comma-separated string
- LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")')
+ LABELS=$(echo "${PULL_REQUEST_LABELS}" | jq -r 'join(",")')
echo "labels=$LABELS" >> $GITHUB_OUTPUT
- name: Check if the `pythonbuild` crate changed
@@ -159,7 +173,7 @@ jobs:
run: |
uv run ci-matrix.py \
--platform linux \
- --labels '${{ steps.get-labels.outputs.labels }}' \
+ --labels '${STEPS_GET_LABELS_OUTPUTS_LABELS}' \
--max-shards 2 \
${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} \
> matrix.json
@@ -179,6 +193,8 @@ jobs:
# Build matrix is empty
echo "any_builds=false" >> $GITHUB_OUTPUT
fi
+ env:
+ STEPS_GET_LABELS_OUTPUTS_LABELS: ${{ steps.get-labels.outputs.labels }}
build-0:
needs:
@@ -198,11 +214,12 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
+ persist-credentials: false
- name: Install Python
uses: actions/setup-python@v5
with:
- python-version: '3.11'
+ python-version: "3.11"
- name: Download pythonbuild
uses: actions/download-artifact@v4
@@ -247,7 +264,11 @@ jobs:
# Touch mtimes of all images so they are newer than autogenerated files above.
touch build/image-*
- ./build-linux.py --target-triple ${{ matrix.target_triple }} --python cpython-${{ matrix.python }} --options ${{ matrix.build_options }}
+ ./build-linux.py --target-triple ${MATRIX_TARGET_TRIPLE} --python cpython-${MATRIX_PYTHON} --options ${MATRIX_BUILD_OPTIONS}
+ env:
+ MATRIX_TARGET_TRIPLE: ${{ matrix.target_triple }}
+ MATRIX_PYTHON: ${{ matrix.python }}
+ MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }}
- name: Generate attestations
uses: actions/attest-build-provenance@v2
@@ -267,8 +288,8 @@ jobs:
run: |
chmod +x build/pythonbuild
- if [ "${{ matrix.run }}" == "true" ]; then
- if [ "${{ matrix.libc }}" == "musl" ]; then
+ if [ "${MATRIX_RUN}" == "true" ]; then
+ if [ "${MATRIX_LIBC}" == "musl" ]; then
sudo apt install musl-dev
# GitHub's setup-python action sets `LD_LIBRARY_PATH` which overrides `RPATH`
@@ -279,6 +300,9 @@ jobs:
fi
build/pythonbuild validate-distribution ${EXTRA_ARGS} dist/*.tar.zst
+ env:
+ MATRIX_RUN: ${{ matrix.run }}
+ MATRIX_LIBC: ${{ matrix.libc }}
build-1:
needs:
@@ -298,11 +322,12 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
+ persist-credentials: false
- name: Install Python
uses: actions/setup-python@v5
with:
- python-version: '3.11'
+ python-version: "3.11"
- name: Download pythonbuild
uses: actions/download-artifact@v4
@@ -347,7 +372,11 @@ jobs:
# Touch mtimes of all images so they are newer than autogenerated files above.
touch build/image-*
- ./build-linux.py --target-triple ${{ matrix.target_triple }} --python cpython-${{ matrix.python }} --options ${{ matrix.build_options }}
+ ./build-linux.py --target-triple ${MATRIX_TARGET_TRIPLE} --python cpython-${MATRIX_PYTHON} --options ${MATRIX_BUILD_OPTIONS}
+ env:
+ MATRIX_TARGET_TRIPLE: ${{ matrix.target_triple }}
+ MATRIX_PYTHON: ${{ matrix.python }}
+ MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }}
- name: Generate attestations
uses: actions/attest-build-provenance@v2
@@ -367,8 +396,8 @@ jobs:
run: |
chmod +x build/pythonbuild
- if [ "${{ matrix.run }}" == "true" ]; then
- if [ "${{ matrix.libc }}" == "musl" ]; then
+ if [ "${MATRIX_RUN}" == "true" ]; then
+ if [ "${MATRIX_LIBC}" == "musl" ]; then
sudo apt install musl-dev
# GitHub's setup-python action sets `LD_LIBRARY_PATH` which overrides `RPATH`
@@ -379,3 +408,6 @@ jobs:
fi
build/pythonbuild validate-distribution ${EXTRA_ARGS} dist/*.tar.zst
+ env:
+ MATRIX_RUN: ${{ matrix.run }}
+ MATRIX_LIBC: ${{ matrix.libc }}
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 1199b39..0bc73b1 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -12,6 +12,8 @@ concurrency:
env:
FORCE_COLOR: 1
+permissions: {}
+
jobs:
crate-build:
needs:
@@ -23,6 +25,8 @@ jobs:
name: crate / ${{ matrix.arch }}
steps:
- uses: actions/checkout@v4
+ with:
+ persist-credentials: false
- name: Emit rustc version
run: |
@@ -47,6 +51,7 @@ jobs:
path: target/release/pythonbuild
generate-matrix:
+ name: Generate build matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
@@ -55,16 +60,19 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
- fetch-depth: 0 # fetch history for subsequent `git diff`
+ fetch-depth: 0
+ persist-credentials: false
- name: Set up Python
uses: astral-sh/setup-uv@v4
- name: Get pull request labels
id: get-labels
+ env:
+ PULL_REQUEST_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
# Convert GitHub labels array to comma-separated string
- LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")')
+ LABELS=$(echo "${PULL_REQUEST_LABELS}" | jq -r 'join(",")')
echo "labels=$LABELS" >> $GITHUB_OUTPUT
- name: Check if the `pythonbuild` crate changed
@@ -82,12 +90,12 @@ jobs:
- name: Generate build matrix
id: set-matrix
run: |
- uv run ci-matrix.py --platform darwin --labels '${{ steps.get-labels.outputs.labels }}' ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json
-
+ uv run ci-matrix.py --platform darwin --labels '${STEPS_GET_LABELS_OUTPUTS_LABELS}' ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json
+
# Extract python-build matrix
echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT
echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT
-
+
# Display the matrix for debugging too
cat matrix.json | jq
@@ -98,6 +106,8 @@ jobs:
# Build matrix is empty
echo "any_builds=false" >> $GITHUB_OUTPUT
fi
+ env:
+ STEPS_GET_LABELS_OUTPUTS_LABELS: ${{ steps.get-labels.outputs.labels }}
build:
needs:
@@ -116,11 +126,12 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
+ persist-credentials: false
- name: Install Python
uses: actions/setup-python@v5
with:
- python-version: '3.11'
+ python-version: "3.11"
- name: Download pythonbuild
uses: actions/download-artifact@v4
@@ -131,16 +142,20 @@ jobs:
- name: Build
if: ${{ ! matrix.dry-run }}
run: |
- if [ "${{ matrix.target_triple }}" = "aarch64-apple-darwin" ]; then
+ if [ "${MATRIX_TARGET_TRIPLE}" = "aarch64-apple-darwin" ]; then
export APPLE_SDK_PATH=/Applications/Xcode_15.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk
- elif [ "${{ matrix.target_triple }}" = "x86_64-apple-darwin" ]; then
+ elif [ "${MATRIX_TARGET_TRIPLE}" = "x86_64-apple-darwin" ]; then
export APPLE_SDK_PATH=/Applications/Xcode_15.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk
else
- echo "unhandled target triple: ${{ matrix.target_triple }}"
+ echo "unhandled target triple: ${MATRIX_TARGET_TRIPLE}"
exit 1
fi
- ./build-macos.py --target-triple ${{ matrix.target_triple }} --python cpython-${{ matrix.python }} --options ${{ matrix.build_options }}
+ ./build-macos.py --target-triple ${MATRIX_TARGET_TRIPLE} --python cpython-${MATRIX_PYTHON} --options ${MATRIX_BUILD_OPTIONS}
+ env:
+ MATRIX_TARGET_TRIPLE: ${{ matrix.target_triple }}
+ MATRIX_PYTHON: ${{ matrix.python }}
+ MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }}
- name: Generate attestations
uses: actions/attest-build-provenance@v2
@@ -159,9 +174,10 @@ jobs:
if: ${{ ! matrix.dry-run }}
uses: actions/checkout@v4
with:
- repository: 'phracker/MacOSX-SDKs'
+ repository: phracker/MacOSX-SDKs
ref: master
path: macosx-sdks
+ persist-credentials: false
- name: Validate Distribution
if: ${{ ! matrix.dry-run }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index a81dc2f..be1c85e 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -18,30 +18,36 @@ on:
env:
FORCE_COLOR: 1
-permissions:
- contents: write
- packages: write
- # Permissions used for actions/attest-build-provenance
- id-token: write
- attestations: write
+permissions: {}
jobs:
release:
+ name: Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
runs-on: ubuntu-latest
+
+ permissions:
+ contents: write
+ packages: write
+ # Permissions used for actions/attest-build-provenance
+ id-token: write
+ attestations: write
+
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
+ persist-credentials: false
- uses: extractions/setup-just@dd310ad5a97d8e7b41793f8ef055398d51ad4de6 # v2
# Perform a release in dry-run mode.
- - run: just release-dry-run ${{ secrets.GITHUB_TOKEN }} ${{ github.event.inputs.sha }} ${{ github.event.inputs.tag }}
+ - run: just release-dry-run ${GH_TOKEN} ${GITHUB_EVENT_INPUTS_SHA} ${GITHUB_EVENT_INPUTS_TAG}
if: ${{ github.event.inputs.dry-run == 'true' }}
-
- # Set our identity for git operations (on the latest-release branch).
+ env:
+ GITHUB_EVENT_INPUTS_SHA: ${{ github.event.inputs.sha }}
+ GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }}
- name: Configure Git identity
if: ${{ github.event.inputs.dry-run == 'false' }}
run: |
@@ -51,28 +57,36 @@ jobs:
# Fetch the commit so that it exists locally.
- name: Fetch commit
if: ${{ github.event.inputs.dry-run == 'false' }}
- run: git fetch origin ${{ github.event.inputs.sha }}
+ run: git fetch origin ${GITHUB_EVENT_INPUTS_SHA}
+ env:
+ GITHUB_EVENT_INPUTS_SHA: ${{ github.event.inputs.sha }}
# Associate the commit with the tag.
- name: Create tag
if: ${{ github.event.inputs.dry-run == 'false' }}
- run: git tag ${{ github.event.inputs.tag }} ${{ github.event.inputs.sha }}
-
- # Push the tag to GitHub.
+ run: git tag ${GITHUB_EVENT_INPUTS_TAG} ${GITHUB_EVENT_INPUTS_SHA}
+ env:
+ GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }}
+ GITHUB_EVENT_INPUTS_SHA: ${{ github.event.inputs.sha }}
- name: Push tag
if: ${{ github.event.inputs.dry-run == 'false' }}
- run: git push origin ${{ github.event.inputs.tag }}
+ run: git push origin ${GITHUB_EVENT_INPUTS_TAG}
+ env:
+ GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }}
# Create a GitHub release.
- name: Create GitHub Release
if: ${{ github.event.inputs.dry-run == 'false' }}
- run: just release-create ${{ github.event.inputs.tag }}
+ run: just release-create ${GITHUB_EVENT_INPUTS_TAG}
+ env:
+ GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }}
# Uploading the relevant artifact to the GitHub release.
- - run: just release-run ${{ secrets.GITHUB_TOKEN }} ${{ github.event.inputs.sha }} ${{ github.event.inputs.tag }}
+ - run: just release-run ${GH_TOKEN} ${GITHUB_EVENT_INPUTS_SHA} ${GITHUB_EVENT_INPUTS_TAG}
if: ${{ github.event.inputs.dry-run == 'false' }}
-
- # We filter by *.tar.@(zst|gz) since actions/attest-build-provenance only supports up to 1024 subjects
+ env:
+ GITHUB_EVENT_INPUTS_SHA: ${{ github.event.inputs.sha }}
+ GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }}
- name: Generate attestations
uses: actions/attest-build-provenance@v2
if: ${{ github.event.inputs.dry-run == 'false' }}
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 165ff26..e1fea41 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -12,6 +12,8 @@ concurrency:
env:
FORCE_COLOR: 1
+permissions: {}
+
jobs:
crate-build:
needs:
@@ -23,6 +25,8 @@ jobs:
name: crate / ${{ matrix.arch }}
steps:
- uses: actions/checkout@v4
+ with:
+ persist-credentials: false
- name: Emit rustc version
run: |
@@ -47,6 +51,7 @@ jobs:
path: target/release/pythonbuild.exe
generate-matrix:
+ name: Generate build matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
@@ -55,16 +60,19 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
- fetch-depth: 0 # fetch history for subsequent `git diff`
+ fetch-depth: 0
+ persist-credentials: false
- name: Set up Python
uses: astral-sh/setup-uv@v4
- name: Get pull request labels
id: get-labels
+ env:
+ PULL_REQUEST_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
# Convert GitHub labels array to comma-separated string
- LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r 'join(",")')
+ LABELS=$(echo "${PULL_REQUEST_LABELS}" | jq -r 'join(",")')
echo "labels=$LABELS" >> $GITHUB_OUTPUT
- name: Check if the `pythonbuild` crate changed
@@ -82,12 +90,12 @@ jobs:
- name: Generate build matrix
id: set-matrix
run: |
- uv run ci-matrix.py --platform windows --labels '${{ steps.get-labels.outputs.labels }}' ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json
-
+ uv run ci-matrix.py --platform windows --labels '${STEPS_GET_LABELS_OUTPUTS_LABELS}' ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json
+
# Extract python-build matrix
echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT
echo "crate-build-matrix=$(jq -c '."crate-build"' matrix.json)" >> $GITHUB_OUTPUT
-
+
# Display the matrix for debugging too
cat matrix.json | jq
@@ -98,6 +106,8 @@ jobs:
# Build matrix is empty
echo "any_builds=false" >> $GITHUB_OUTPUT
fi
+ env:
+ STEPS_GET_LABELS_OUTPUTS_LABELS: ${{ steps.get-labels.outputs.labels }}
build:
timeout-minutes: 60
@@ -117,6 +127,7 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
+ persist-credentials: false
- name: Install Cygwin Environment
uses: cygwin/cygwin-install-action@49f298a7ebb00d4b3ddf58000c3e78eff5fbd6b9 # v2
@@ -126,7 +137,7 @@ jobs:
- name: Install Python
uses: actions/setup-python@v5
with:
- python-version: '3.12'
+ python-version: "3.12"
- name: Download pythonbuild Executable
uses: actions/download-artifact@v4
@@ -143,8 +154,12 @@ jobs:
if: ${{ ! matrix.dry-run }}
shell: cmd
run: |
- call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\${{ matrix.vcvars }}"
- py.exe -3.12 build-windows.py --python cpython-${{ matrix.python }} --sh c:\cygwin\bin\sh.exe --options ${{ matrix.build_options }}
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\%MATRIX_VCVARS%"
+ py.exe -3.12 build-windows.py --python cpython-%MATRIX_PYTHON% --sh c:\cygwin\bin\sh.exe --options %MATRIX_BUILD_OPTIONS%
+ env:
+ MATRIX_VCVARS: ${{ matrix.vcvars }}
+ MATRIX_PYTHON: ${{ matrix.python }}
+ MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }}
- name: Generate attestations
uses: actions/attest-build-provenance@v2
diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml
new file mode 100644
index 0000000..a60e286
--- /dev/null
+++ b/.github/workflows/zizmor.yml
@@ -0,0 +1,24 @@
+name: zizmor
+
+on:
+ push:
+ branches: ["main"]
+ pull_request:
+ branches: ["**"]
+
+permissions: {}
+
+jobs:
+ zizmor:
+ name: Run zizmor
+ runs-on: ubuntu-latest
+ permissions:
+ security-events: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ with:
+ persist-credentials: false
+
+ - name: Run zizmor
+ uses: zizmorcore/zizmor-action@f52a838cfabf134edcbaa7c8b3677dde20045018 # v0.1.1
diff --git a/.github/zizmor.yml b/.github/zizmor.yml
new file mode 100644
index 0000000..c3db968
--- /dev/null
+++ b/.github/zizmor.yml
@@ -0,0 +1,7 @@
+rules:
+ unpinned-uses:
+ config:
+ policies:
+ actions/*: ref-pin
+ astral-sh/*: ref-pin
+ "*": hash-pin
From 55f3d50aee9743ea48afaa18d43ff7a96af7b056 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 4 Aug 2025 16:19:36 -0500
Subject: [PATCH 39/72] Bump the actions group in /.github/workflows with 3
updates (#718)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps the actions group in /.github/workflows with 3 updates:
[docker/setup-buildx-action](https://github.com/docker/setup-buildx-action),
[extractions/setup-just](https://github.com/extractions/setup-just) and
[cygwin/cygwin-install-action](https://github.com/cygwin/cygwin-install-action).
Updates `docker/setup-buildx-action` from 3.10.0 to 3.11.1
Release notes
Sourced from docker/setup-buildx-action's
releases.
v3.11.1
Full Changelog: https://github.com/docker/setup-buildx-action/compare/v3.11.0...v3.11.1
v3.11.0
Full Changelog: https://github.com/docker/setup-buildx-action/compare/v3.10.0...v3.11.0
Commits
e468171
Merge pull request #429
from crazy-max/fix-keep-state
a3e7502
chore: update generated content
b145473
fix keep-state not being respected
18ce135
Merge pull request #425
from docker/dependabot/npm_and_yarn/docker/actions-to...
0e198e9
chore: update generated content
05f3f3a
build(deps): bump @docker/actions-toolkit from 0.61.0 to
0.62.1
6229134
Merge pull request #427
from crazy-max/keep-state
c6f6a07
chore: update generated content
6c5e29d
skip builder creation if one already exists with the same name
548b297
ci: keep-state check
- Additional commits viewable in compare
view
Updates `extractions/setup-just` from 2.0.0 to 3.0.0
Commits
Updates `cygwin/cygwin-install-action` from 2 to 6
Release notes
Sourced from cygwin/cygwin-install-action's
releases.
v6
What's Changed
New Contributors
Full Changelog: https://github.com/cygwin/cygwin-install-action/compare/v5...v6
v5
What's Changed
New Contributors
Full Changelog: https://github.com/cygwin/cygwin-install-action/compare/v4...v5
v4
No release notes provided.
v3
No release notes provided.
Commits
f200932
Give the action some outputs
52b4c10
Check Authenticode signature on setup
e67b1f4
Factor out download retry as a function, to use on sha512.sum file
also
8381d6d
Add a retry mechanism for fetching setup executable
354b337
Consistently use throw to terminate with an error
f623c57
Add a test of work-vol option
d3a7464
Use D: drive as default work-vol
1c9eb7c
Add work-vol option to target different setup volume
d6a07e1
Tweak wording about SHELLOPTS and line-endings
63d1e75
Add warning about using SHELLOPTS to set igncr
- Additional commits viewable in compare
view
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore ` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore ` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore ` will
remove the ignore condition of the specified dependency and ignore
conditions
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/linux.yml | 2 +-
.github/workflows/release.yml | 2 +-
.github/workflows/windows.yml | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 2ed390b..2d8c8a1 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -77,7 +77,7 @@ jobs:
python-version: "3.11"
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
+ uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3
- name: Login to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index be1c85e..f4036a0 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -40,7 +40,7 @@ jobs:
submodules: recursive
persist-credentials: false
- - uses: extractions/setup-just@dd310ad5a97d8e7b41793f8ef055398d51ad4de6 # v2
+ - uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v2
# Perform a release in dry-run mode.
- run: just release-dry-run ${GH_TOKEN} ${GITHUB_EVENT_INPUTS_SHA} ${GITHUB_EVENT_INPUTS_TAG}
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index e1fea41..14840f4 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -130,7 +130,7 @@ jobs:
persist-credentials: false
- name: Install Cygwin Environment
- uses: cygwin/cygwin-install-action@49f298a7ebb00d4b3ddf58000c3e78eff5fbd6b9 # v2
+ uses: cygwin/cygwin-install-action@f2009323764960f80959895c7bc3bb30210afe4d # v6
with:
packages: autoconf automake libtool
From b670cd8b835d206c521a70863080762b98455b09 Mon Sep 17 00:00:00 2001
From: Nathan Cain <13713501+nathanscain@users.noreply.github.com>
Date: Wed, 6 Aug 2025 16:04:21 -0500
Subject: [PATCH 40/72] apply disable-multiarch patch to all musl builds (#725)
Potential solve for #724
---
cpython-unix/build-cpython.sh | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index cc93f0a..3c252a5 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -116,17 +116,12 @@ fi
# Clang 13 actually prints something with --print-multiarch, confusing CPython's
# configure. This is reported as https://bugs.python.org/issue45405. We nerf the
# check since we know what we're doing.
-if [ "${CC}" = "clang" ]; then
+if [[ "${CC}" = "clang" || "${CC}" = "musl-clang" ]]; then
if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then
patch -p1 -i ${ROOT}/patch-disable-multiarch-13.patch
else
patch -p1 -i ${ROOT}/patch-disable-multiarch.patch
fi
-elif [ "${CC}" = "musl-clang" ]; then
- # Similarly, this is a problem for musl Clang on Python 3.13+
- if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then
- patch -p1 -i ${ROOT}/patch-disable-multiarch-13.patch
- fi
fi
# Python 3.11 supports using a provided Python to use during bootstrapping
From be22cba141e263d56d40f78c7fb910ef8916d86b Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Wed, 6 Aug 2025 17:34:36 -0500
Subject: [PATCH 41/72] Bump CPython 3.13 version to 3.13.6 (#726)
---
cpython-unix/build-cpython.sh | 7 -
.../patch-uuid-getnode-stable-3.13.patch | 708 ------------------
pythonbuild/downloads.py | 8 +-
3 files changed, 4 insertions(+), 719 deletions(-)
delete mode 100644 cpython-unix/patch-uuid-getnode-stable-3.13.patch
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index 3c252a5..04dab67 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -76,13 +76,6 @@ if [ -n "${CROSS_COMPILING}" ]; then
fi
fi
-# `uuid.getnode()` is not stable on our libuuid, CPython should fallback to another method
-# Cherry-pick https://github.com/python/cpython/pull/134704 until it is released
-# We could backport this to more versions too, it won't be done by the upstream
-if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" && -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_13}" ]]; then
- patch -p1 -i ${ROOT}/patch-uuid-getnode-stable-3.13.patch
-fi
-
# This patch is slightly different on Python 3.10+.
if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_10}" ]; then
patch -p1 -i ${ROOT}/patch-xopen-source-ios.patch
diff --git a/cpython-unix/patch-uuid-getnode-stable-3.13.patch b/cpython-unix/patch-uuid-getnode-stable-3.13.patch
deleted file mode 100644
index 11bdf83..0000000
--- a/cpython-unix/patch-uuid-getnode-stable-3.13.patch
+++ /dev/null
@@ -1,708 +0,0 @@
-diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py
-index e7e44c6413c2e2..ce396aa942b6ed 100755
---- a/Lib/test/test_uuid.py
-+++ b/Lib/test/test_uuid.py
-@@ -1,6 +1,7 @@
- import unittest
- from test import support
- from test.support import import_helper
-+from test.support.script_helper import assert_python_ok
- import builtins
- import contextlib
- import copy
-@@ -773,10 +774,37 @@ def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self):
- class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase):
- uuid = py_uuid
-
-+
- @unittest.skipUnless(c_uuid, 'requires the C _uuid module')
- class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
- uuid = c_uuid
-
-+ def check_has_stable_libuuid_extractable_node(self):
-+ if not self.uuid._has_stable_extractable_node:
-+ self.skipTest("libuuid cannot deduce MAC address")
-+
-+ @unittest.skipUnless(os.name == 'posix', 'POSIX only')
-+ def test_unix_getnode_from_libuuid(self):
-+ self.check_has_stable_libuuid_extractable_node()
-+ script = 'import uuid; print(uuid._unix_getnode())'
-+ _, n_a, _ = assert_python_ok('-c', script)
-+ _, n_b, _ = assert_python_ok('-c', script)
-+ n_a, n_b = n_a.decode().strip(), n_b.decode().strip()
-+ self.assertTrue(n_a.isdigit())
-+ self.assertTrue(n_b.isdigit())
-+ self.assertEqual(n_a, n_b)
-+
-+ @unittest.skipUnless(os.name == 'nt', 'Windows only')
-+ def test_windows_getnode_from_libuuid(self):
-+ self.check_has_stable_libuuid_extractable_node()
-+ script = 'import uuid; print(uuid._windll_getnode())'
-+ _, n_a, _ = assert_python_ok('-c', script)
-+ _, n_b, _ = assert_python_ok('-c', script)
-+ n_a, n_b = n_a.decode().strip(), n_b.decode().strip()
-+ self.assertTrue(n_a.isdigit())
-+ self.assertTrue(n_b.isdigit())
-+ self.assertEqual(n_a, n_b)
-+
-
- class BaseTestInternals:
- _uuid = py_uuid
-diff --git a/Lib/uuid.py b/Lib/uuid.py
-index c286eac38e1ef4..6ab1658cc5249a 100644
---- a/Lib/uuid.py
-+++ b/Lib/uuid.py
-@@ -572,22 +572,24 @@ def _netstat_getnode():
- try:
- import _uuid
- _generate_time_safe = getattr(_uuid, "generate_time_safe", None)
-+ _has_stable_extractable_node = getattr(_uuid, "has_stable_extractable_node", False)
- _UuidCreate = getattr(_uuid, "UuidCreate", None)
- except ImportError:
- _uuid = None
- _generate_time_safe = None
-+ _has_stable_extractable_node = False
- _UuidCreate = None
-
-
- def _unix_getnode():
- """Get the hardware address on Unix using the _uuid extension module."""
-- if _generate_time_safe:
-+ if _generate_time_safe and _has_stable_extractable_node:
- uuid_time, _ = _generate_time_safe()
- return UUID(bytes=uuid_time).node
-
- def _windll_getnode():
- """Get the hardware address on Windows using the _uuid extension module."""
-- if _UuidCreate:
-+ if _UuidCreate and _has_stable_extractable_node:
- uuid_bytes = _UuidCreate()
- return UUID(bytes_le=uuid_bytes).node
-
-diff --git a/Modules/_uuidmodule.c b/Modules/_uuidmodule.c
-index c5e78b1510b5e3..c31a7e8fea5608 100644
---- a/Modules/_uuidmodule.c
-+++ b/Modules/_uuidmodule.c
-@@ -78,23 +78,47 @@ py_UuidCreate(PyObject *Py_UNUSED(context),
- return NULL;
- }
-
-+static int
-+py_windows_has_stable_node(void)
-+{
-+ UUID uuid;
-+ RPC_STATUS res;
-+ Py_BEGIN_ALLOW_THREADS
-+ res = UuidCreateSequential(&uuid);
-+ Py_END_ALLOW_THREADS
-+ return res == RPC_S_OK;
-+}
- #endif /* MS_WINDOWS */
-
-
- static int
--uuid_exec(PyObject *module) {
-+uuid_exec(PyObject *module)
-+{
-+#define ADD_INT(NAME, VALUE) \
-+ do { \
-+ if (PyModule_AddIntConstant(module, (NAME), (VALUE)) < 0) { \
-+ return -1; \
-+ } \
-+ } while (0)
-+
- assert(sizeof(uuid_t) == 16);
- #if defined(MS_WINDOWS)
-- int has_uuid_generate_time_safe = 0;
-+ ADD_INT("has_uuid_generate_time_safe", 0);
- #elif defined(HAVE_UUID_GENERATE_TIME_SAFE)
-- int has_uuid_generate_time_safe = 1;
-+ ADD_INT("has_uuid_generate_time_safe", 1);
- #else
-- int has_uuid_generate_time_safe = 0;
-+ ADD_INT("has_uuid_generate_time_safe", 0);
- #endif
-- if (PyModule_AddIntConstant(module, "has_uuid_generate_time_safe",
-- has_uuid_generate_time_safe) < 0) {
-- return -1;
-- }
-+
-+#if defined(MS_WINDOWS)
-+ ADD_INT("has_stable_extractable_node", py_windows_has_stable_node());
-+#elif defined(HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC)
-+ ADD_INT("has_stable_extractable_node", 1);
-+#else
-+ ADD_INT("has_stable_extractable_node", 0);
-+#endif
-+
-+#undef ADD_INT
- return 0;
- }
-
-diff --git a/configure b/configure
-index 1cd1f690f7b9c1..cc976aafc09b34 100755
---- a/configure
-+++ b/configure
-@@ -13381,6 +13381,7 @@ fi
-
-
-
-+
- have_uuid=missing
-
- for ac_header in uuid.h
-@@ -13390,6 +13391,7 @@ if test "x$ac_cv_header_uuid_h" = xyes
- then :
- printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h
-
-+
- for ac_func in uuid_create uuid_enc_be
- do :
- as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh`
-@@ -13399,7 +13401,9 @@ then :
- cat >>confdefs.h <<_ACEOF
- #define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1
- _ACEOF
-- have_uuid=yes
-+
-+ have_uuid=yes
-+ ac_cv_have_uuid_h=yes
- LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""}
- LIBUUID_LIBS=${LIBUUID_LIBS-""}
-
-@@ -13489,6 +13493,7 @@ if test "x$ac_cv_header_uuid_uuid_h" = xyes
- then :
- printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h
-
-+ ac_cv_have_uuid_uuid_h=yes
- py_check_lib_save_LIBS=$LIBS
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5
- printf %s "checking for uuid_generate_time in -luuid... " >&6; }
-@@ -13570,8 +13575,9 @@ fi
- printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; }
- if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes
- then :
-- have_uuid=yes
-- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h
-+
-+ have_uuid=yes
-+ ac_cv_have_uuid_generate_time_safe=yes
-
- fi
-
-@@ -13615,6 +13621,7 @@ if test "x$ac_cv_header_uuid_uuid_h" = xyes
- then :
- printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h
-
-+ ac_cv_have_uuid_uuid_h=yes
- py_check_lib_save_LIBS=$LIBS
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5
- printf %s "checking for uuid_generate_time in -luuid... " >&6; }
-@@ -13696,8 +13703,9 @@ fi
- printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; }
- if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes
- then :
-- have_uuid=yes
-- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h
-+
-+ have_uuid=yes
-+ ac_cv_have_uuid_generate_time_safe=yes
-
- fi
-
-@@ -13727,11 +13735,25 @@ else
- LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
- printf "%s\n" "yes" >&6; }
-+<<<<<<< HEAD
- have_uuid=yes
- printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h
-
- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h
-
-+=======
-+ have_uuid=yes
-+ ac_cv_have_uuid_generate_time_safe=yes
-+ # The uuid.h file to include may be *or* .
-+ # Since pkg-config --cflags uuid may return -I/usr/include/uuid,
-+ # it's possible to write '#include ' in _uuidmodule.c,
-+ # assuming that the compiler flags are properly updated.
-+ #
-+ # Ideally, we should have defined HAVE_UUID_H if and only if
-+ # #include can be written, *without* assuming extra
-+ # include path.
-+ ac_cv_have_uuid_h=yes
-+>>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901))
-
- fi
-
-@@ -13752,6 +13774,7 @@ if test "x$ac_cv_func_uuid_generate_time" = xyes
- then :
-
- have_uuid=yes
-+ ac_cv_have_uuid_uuid_h=yes
- LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""}
- LIBUUID_LIBS=${LIBUUID_LIBS-""}
-
-@@ -13764,11 +13787,198 @@ done
-
- fi
-
-+<<<<<<< HEAD
-+=======
-+if test "x$ac_cv_have_uuid_h" = xyes
-+then :
-+ printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h
-+
-+fi
-+if test "x$ac_cv_have_uuid_uuid_h" = xyes
-+then :
-+ printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h
-+
-+fi
-+if test "x$ac_cv_have_uuid_generate_time_safe" = xyes
-+then :
-+
-+ printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h
-+
-+
-+fi
-+
-+# gh-124228: While the libuuid library is available on NetBSD, it supports only UUID version 4.
-+# This restriction inhibits the proper generation of time-based UUIDs.
-+if test "$ac_sys_system" = "NetBSD"; then
-+ have_uuid=missing
-+ printf "%s\n" "#define HAVE_UUID_H 0" >>confdefs.h
-+
-+fi
-+
-+>>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901))
- if test "x$have_uuid" = xmissing
- then :
- have_uuid=no
- fi
-
-+# gh-132710: The UUID node is fetched by using libuuid when possible
-+# and cached. While the node is constant within the same process,
-+# different interpreters may have different values as libuuid may
-+# randomize the node value if the latter cannot be deduced.
-+#
-+# Consumers may define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC
-+# to indicate that libuuid is unstable and should not be relied
-+# upon to deduce the MAC address.
-+
-+
-+if test "$have_uuid" = "yes" -a "$HAVE_UUID_GENERATE_TIME_SAFE" = "1"
-+then
-+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if uuid_generate_time_safe() node value is stable" >&5
-+printf %s "checking if uuid_generate_time_safe() node value is stable... " >&6; }
-+ save_CFLAGS=$CFLAGS
-+save_CPPFLAGS=$CPPFLAGS
-+save_LDFLAGS=$LDFLAGS
-+save_LIBS=$LIBS
-+
-+
-+ # Be sure to add the extra include path if we used pkg-config
-+ # as HAVE_UUID_H may be set even though is only reachable
-+ # by adding extra -I flags.
-+ #
-+ # If the following script does not compile, we simply assume that
-+ # libuuid is missing.
-+ CFLAGS="$CFLAGS $LIBUUID_CFLAGS"
-+ LIBS="$LIBS $LIBUUID_LIBS"
-+ if test "$cross_compiling" = yes
-+then :
-+
-+
-+else case e in #(
-+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-+/* end confdefs.h. */
-+
-+ #include // PRIu64
-+ #include // uint64_t
-+ #include // fopen(), fclose()
-+
-+ #ifdef HAVE_UUID_H
-+ #include
-+ #else
-+ #include
-+ #endif
-+
-+ #define ERR 1
-+ int main(void) {
-+ uuid_t uuid; // unsigned char[16]
-+ (void)uuid_generate_time_safe(uuid);
-+ uint64_t node = 0;
-+ for (size_t i = 0; i < 6; i++) {
-+ node |= (uint64_t)uuid[15 - i] << (8 * i);
-+ }
-+ FILE *fp = fopen("conftest.out", "w");
-+ if (fp == NULL) {
-+ return ERR;
-+ }
-+ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0;
-+ rc |= fclose(fp);
-+ return rc == 0 ? 0 : ERR;
-+ }
-+_ACEOF
-+if ac_fn_c_try_run "$LINENO"
-+then :
-+
-+ py_cv_uuid_node1=`cat conftest.out`
-+
-+fi
-+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-+ conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
-+esac
-+fi
-+
-+CFLAGS=$save_CFLAGS
-+CPPFLAGS=$save_CPPFLAGS
-+LDFLAGS=$save_LDFLAGS
-+LIBS=$save_LIBS
-+
-+
-+ save_CFLAGS=$CFLAGS
-+save_CPPFLAGS=$CPPFLAGS
-+save_LDFLAGS=$LDFLAGS
-+save_LIBS=$LIBS
-+
-+
-+ # Be sure to add the extra include path if we used pkg-config
-+ # as HAVE_UUID_H may be set even though is only reachable
-+ # by adding extra -I flags.
-+ #
-+ # If the following script does not compile, we simply assume that
-+ # libuuid is missing.
-+ CFLAGS="$CFLAGS $LIBUUID_CFLAGS"
-+ LIBS="$LIBS $LIBUUID_LIBS"
-+ if test "$cross_compiling" = yes
-+then :
-+
-+
-+else case e in #(
-+ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-+/* end confdefs.h. */
-+
-+ #include // PRIu64
-+ #include // uint64_t
-+ #include // fopen(), fclose()
-+
-+ #ifdef HAVE_UUID_H
-+ #include
-+ #else
-+ #include
-+ #endif
-+
-+ #define ERR 1
-+ int main(void) {
-+ uuid_t uuid; // unsigned char[16]
-+ (void)uuid_generate_time_safe(uuid);
-+ uint64_t node = 0;
-+ for (size_t i = 0; i < 6; i++) {
-+ node |= (uint64_t)uuid[15 - i] << (8 * i);
-+ }
-+ FILE *fp = fopen("conftest.out", "w");
-+ if (fp == NULL) {
-+ return ERR;
-+ }
-+ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0;
-+ rc |= fclose(fp);
-+ return rc == 0 ? 0 : ERR;
-+ }
-+_ACEOF
-+if ac_fn_c_try_run "$LINENO"
-+then :
-+
-+ py_cv_uuid_node2=`cat conftest.out`
-+
-+fi
-+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-+ conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
-+esac
-+fi
-+
-+CFLAGS=$save_CFLAGS
-+CPPFLAGS=$save_CPPFLAGS
-+LDFLAGS=$save_LDFLAGS
-+LIBS=$save_LIBS
-+
-+
-+ if test -n "$py_cv_uuid_node1" -a "$py_cv_uuid_node1" = "$py_cv_uuid_node2"
-+ then
-+ printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC 1" >>confdefs.h
-+
-+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: stable" >&5
-+printf "%s\n" "stable" >&6; }
-+ else
-+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unstable" >&5
-+printf "%s\n" "unstable" >&6; }
-+ fi
-+fi
-+
- # 'Real Time' functions on Solaris
- # posix4 on Solaris 2.6
- # pthread (first!) on Linux
-diff --git a/configure.ac b/configure.ac
-index 3fcb18922c5330..9898af7ffd5f25 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -3740,15 +3740,17 @@ dnl check for uuid dependencies
- AH_TEMPLATE([HAVE_UUID_H], [Define to 1 if you have the header file.])
- AH_TEMPLATE([HAVE_UUID_UUID_H], [Define to 1 if you have the header file.])
- AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE], [Define if uuid_generate_time_safe() exists.])
-+AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC], [Define if uuid_generate_time_safe() is able to deduce a MAC address.])
- have_uuid=missing
-
- dnl AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1
- dnl (anno 2007). FreeBSD and OpenBSD provides support in libc as well.
- dnl Little-endian FreeBSD, OpenBSD and NetBSD needs encoding into an octet
- dnl stream in big-endian byte-order
--AC_CHECK_HEADERS([uuid.h],
-- [AC_CHECK_FUNCS([uuid_create uuid_enc_be],
-- [have_uuid=yes
-+AC_CHECK_HEADERS([uuid.h], [
-+ AC_CHECK_FUNCS([uuid_create uuid_enc_be], [
-+ have_uuid=yes
-+ ac_cv_have_uuid_h=yes
- LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""}
- LIBUUID_LIBS=${LIBUUID_LIBS-""}
- ])
-@@ -3758,19 +3760,29 @@ AS_VAR_IF([have_uuid], [missing], [
- PKG_CHECK_MODULES(
- [LIBUUID], [uuid >= 2.20],
- [dnl linux-util's libuuid has uuid_generate_time_safe() since v2.20 (2011)
-- dnl and provides .
-+ dnl and provides assuming specific include paths are given
- have_uuid=yes
-- AC_DEFINE([HAVE_UUID_H], [1])
-- AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1])
-+ ac_cv_have_uuid_generate_time_safe=yes
-+ # The uuid.h file to include may be *or* .
-+ # Since pkg-config --cflags uuid may return -I/usr/include/uuid,
-+ # it's possible to write '#include ' in _uuidmodule.c,
-+ # assuming that the compiler flags are properly updated.
-+ #
-+ # Ideally, we should have defined HAVE_UUID_H if and only if
-+ # #include can be written, *without* assuming extra
-+ # include path.
-+ ac_cv_have_uuid_h=yes
- ], [
- WITH_SAVE_ENV([
- CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS"
- LIBS="$LIBS $LIBUUID_LIBS"
- AC_CHECK_HEADERS([uuid/uuid.h], [
-+ ac_cv_have_uuid_uuid_h=yes
- PY_CHECK_LIB([uuid], [uuid_generate_time], [have_uuid=yes])
-- PY_CHECK_LIB([uuid], [uuid_generate_time_safe],
-- [have_uuid=yes
-- AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) ]) ])
-+ PY_CHECK_LIB([uuid], [uuid_generate_time_safe], [
-+ have_uuid=yes
-+ ac_cv_have_uuid_generate_time_safe=yes
-+ ])])
- AS_VAR_IF([have_uuid], [yes], [
- LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""}
- LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"}
-@@ -3785,14 +3797,90 @@ AS_VAR_IF([have_uuid], [missing], [
- AC_CHECK_HEADERS([uuid/uuid.h], [
- AC_CHECK_FUNC([uuid_generate_time], [
- have_uuid=yes
-+ ac_cv_have_uuid_uuid_h=yes
- LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""}
- LIBUUID_LIBS=${LIBUUID_LIBS-""}
- ])
- ])
- ])
-
-+AS_VAR_IF([ac_cv_have_uuid_h], [yes], [AC_DEFINE([HAVE_UUID_H], [1])])
-+AS_VAR_IF([ac_cv_have_uuid_uuid_h], [yes], [AC_DEFINE([HAVE_UUID_UUID_H], [1])])
-+AS_VAR_IF([ac_cv_have_uuid_generate_time_safe], [yes], [
-+ AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1])
-+])
-+
-+# gh-124228: While the libuuid library is available on NetBSD, it supports only UUID version 4.
-+# This restriction inhibits the proper generation of time-based UUIDs.
-+if test "$ac_sys_system" = "NetBSD"; then
-+ have_uuid=missing
-+ AC_DEFINE([HAVE_UUID_H], [0])
-+fi
-+
- AS_VAR_IF([have_uuid], [missing], [have_uuid=no])
-
-+# gh-132710: The UUID node is fetched by using libuuid when possible
-+# and cached. While the node is constant within the same process,
-+# different interpreters may have different values as libuuid may
-+# randomize the node value if the latter cannot be deduced.
-+#
-+# Consumers may define HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC
-+# to indicate that libuuid is unstable and should not be relied
-+# upon to deduce the MAC address.
-+AC_DEFUN([PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC], [WITH_SAVE_ENV([
-+ # Be sure to add the extra include path if we used pkg-config
-+ # as HAVE_UUID_H may be set even though is only reachable
-+ # by adding extra -I flags.
-+ #
-+ # If the following script does not compile, we simply assume that
-+ # libuuid is missing.
-+ CFLAGS="$CFLAGS $LIBUUID_CFLAGS"
-+ LIBS="$LIBS $LIBUUID_LIBS"
-+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
-+ #include // PRIu64
-+ #include // uint64_t
-+ #include // fopen(), fclose()
-+
-+ #ifdef HAVE_UUID_H
-+ #include
-+ #else
-+ #include
-+ #endif
-+
-+ #define ERR 1
-+ int main(void) {
-+ uuid_t uuid; // unsigned char[16]
-+ (void)uuid_generate_time_safe(uuid);
-+ uint64_t node = 0;
-+ for (size_t i = 0; i < 6; i++) {
-+ node |= (uint64_t)uuid[15 - i] << (8 * i);
-+ }
-+ FILE *fp = fopen("conftest.out", "w");
-+ if (fp == NULL) {
-+ return ERR;
-+ }
-+ int rc = fprintf(fp, "%" PRIu64 "\n", node) >= 0;
-+ rc |= fclose(fp);
-+ return rc == 0 ? 0 : ERR;
-+ }]])], [
-+ AS_VAR_SET([$1], [`cat conftest.out`])
-+ ], [], []
-+ )])])
-+
-+if test "$have_uuid" = "yes" -a "$HAVE_UUID_GENERATE_TIME_SAFE" = "1"
-+then
-+ AC_MSG_CHECKING([if uuid_generate_time_safe() node value is stable])
-+ PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC([py_cv_uuid_node1])
-+ PY_EXTRACT_UUID_GENERATE_TIME_SAFE_MAC([py_cv_uuid_node2])
-+ if test -n "$py_cv_uuid_node1" -a "$py_cv_uuid_node1" = "$py_cv_uuid_node2"
-+ then
-+ AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC], [1])
-+ AC_MSG_RESULT([stable])
-+ else
-+ AC_MSG_RESULT([unstable])
-+ fi
-+fi
-+
- # 'Real Time' functions on Solaris
- # posix4 on Solaris 2.6
- # pthread (first!) on Linux
-diff --git a/pyconfig.h.in b/pyconfig.h.in
-index 3c16c694c84599..73358a0f35ae82 100644
---- a/pyconfig.h.in
-+++ b/pyconfig.h.in
-@@ -1548,6 +1548,9 @@
- /* Define if uuid_generate_time_safe() exists. */
- #undef HAVE_UUID_GENERATE_TIME_SAFE
-
-+/* Define if uuid_generate_time_safe() is able to deduce a MAC address. */
-+#undef HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC
-+
- /* Define to 1 if you have the header file. */
- #undef HAVE_UUID_H
-
-
-From cb0f32a7d64b6dc4a63c4a683bb52a97ebe1d78a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?=
- <10796600+picnixz@users.noreply.github.com>
-Date: Mon, 26 May 2025 12:34:00 +0200
-Subject: [PATCH 2/2] rgen
-
----
- configure | 25 ++++++-------------------
- 1 file changed, 6 insertions(+), 19 deletions(-)
-
-diff --git a/configure b/configure
-index cc976aafc09b34..47e4f29e23a7ac 100755
---- a/configure
-+++ b/configure
-@@ -13735,14 +13735,7 @@ else
- LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
- printf "%s\n" "yes" >&6; }
--<<<<<<< HEAD
- have_uuid=yes
-- printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h
--
-- printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h
--
--=======
-- have_uuid=yes
- ac_cv_have_uuid_generate_time_safe=yes
- # The uuid.h file to include may be *or* .
- # Since pkg-config --cflags uuid may return -I/usr/include/uuid,
-@@ -13753,7 +13746,6 @@ printf "%s\n" "yes" >&6; }
- # #include can be written, *without* assuming extra
- # include path.
- ac_cv_have_uuid_h=yes
-->>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901))
-
- fi
-
-@@ -13787,8 +13779,6 @@ done
-
- fi
-
--<<<<<<< HEAD
--=======
- if test "x$ac_cv_have_uuid_h" = xyes
- then :
- printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h
-@@ -13815,7 +13805,6 @@ if test "$ac_sys_system" = "NetBSD"; then
-
- fi
-
-->>>>>>> 3bffada4672 (gh-132710: only use stable `_uuid.generate_time_safe()` to deduce MAC address (#132901))
- if test "x$have_uuid" = xmissing
- then :
- have_uuid=no
-@@ -13853,8 +13842,8 @@ save_LIBS=$LIBS
- then :
-
-
--else case e in #(
-- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-+else $as_nop
-+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
- /* end confdefs.h. */
-
- #include // PRIu64
-@@ -13891,8 +13880,7 @@ then :
-
- fi
- rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-- conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
--esac
-+ conftest.$ac_objext conftest.beam conftest.$ac_ext
- fi
-
- CFLAGS=$save_CFLAGS
-@@ -13919,8 +13907,8 @@ save_LIBS=$LIBS
- then :
-
-
--else case e in #(
-- e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-+else $as_nop
-+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
- /* end confdefs.h. */
-
- #include // PRIu64
-@@ -13957,8 +13945,7 @@ then :
-
- fi
- rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-- conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
--esac
-+ conftest.$ac_objext conftest.beam conftest.$ac_ext
- fi
-
- CFLAGS=$save_CFLAGS
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index 78a2401..7d80e34 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -73,10 +73,10 @@
"python_tag": "cp312",
},
"cpython-3.13": {
- "url": "https://www.python.org/ftp/python/3.13.5/Python-3.13.5.tar.xz",
- "size": 22856016,
- "sha256": "93e583f243454e6e9e4588ca2c2662206ad961659863277afcdb96801647d640",
- "version": "3.13.5",
+ "url": "https://www.python.org/ftp/python/3.13.6/Python-3.13.6.tar.xz",
+ "size": 22761268,
+ "sha256": "17ba5508819d8736a14fbfc47d36e184946a877851b2e9c4b6c43acb44a3b104",
+ "version": "3.13.6",
"licenses": ["Python-2.0", "CNRI-Python"],
"license_file": "LICENSE.cpython.txt",
"python_tag": "cp313",
From 4cfefb552ebbe0f935cecc9669714f02568347d4 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Thu, 7 Aug 2025 08:03:34 -0500
Subject: [PATCH 42/72] Fix label subsetting (#731)
Regressed in #716
---
.github/workflows/linux.yml | 2 +-
.github/workflows/macos.yml | 2 +-
.github/workflows/windows.yml | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 2d8c8a1..edd5acb 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -173,7 +173,7 @@ jobs:
run: |
uv run ci-matrix.py \
--platform linux \
- --labels '${STEPS_GET_LABELS_OUTPUTS_LABELS}' \
+ --labels "${STEPS_GET_LABELS_OUTPUTS_LABELS}" \
--max-shards 2 \
${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} \
> matrix.json
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 0bc73b1..02ce471 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -90,7 +90,7 @@ jobs:
- name: Generate build matrix
id: set-matrix
run: |
- uv run ci-matrix.py --platform darwin --labels '${STEPS_GET_LABELS_OUTPUTS_LABELS}' ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json
+ uv run ci-matrix.py --platform darwin --labels "${STEPS_GET_LABELS_OUTPUTS_LABELS}" ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json
# Extract python-build matrix
echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 14840f4..847a82e 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -90,7 +90,7 @@ jobs:
- name: Generate build matrix
id: set-matrix
run: |
- uv run ci-matrix.py --platform windows --labels '${STEPS_GET_LABELS_OUTPUTS_LABELS}' ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json
+ uv run ci-matrix.py --platform windows --labels "${STEPS_GET_LABELS_OUTPUTS_LABELS}" ${{ (steps.check-pythonbuild.outputs.changed == 'true' || github.ref == 'refs/heads/main') && '--force-crate-build' || '' }} > matrix.json
# Extract python-build matrix
echo "matrix=$(jq -c '."python-build"' matrix.json)" >> $GITHUB_OUTPUT
From 281d11620539c54ad3dd9d35b727109d36c644f6 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Thu, 7 Aug 2025 13:41:48 -0500
Subject: [PATCH 43/72] Persist credentials in the release workflow (#729)
Co-authored-by: William Woodruff
---
.github/workflows/release.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f4036a0..37edc1b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -38,7 +38,7 @@ jobs:
- uses: actions/checkout@v4
with:
submodules: recursive
- persist-credentials: false
+ persist-credentials: true # needed for git operations below
- uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v2
From cb554c8f75d2cd9e4828c753c1977b7c4d3a72e6 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Thu, 7 Aug 2025 13:47:53 -0500
Subject: [PATCH 44/72] Use a larger runner again for the release (#733)
We need more disk space.
Partially reverts
https://github.com/astral-sh/python-build-standalone/commit/a376f32981a4e690963fe29a6ae31203afb440ae
though I'm using an 8-core instead of 16-core runner and Depot instead
of GitHub.
---
.github/workflows/release.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 37edc1b..9c256ee 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -25,7 +25,7 @@ jobs:
name: Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- runs-on: ubuntu-latest
+ runs-on: depot-ubuntu-24.04-8
permissions:
contents: write
From 7c96f41400198c589039c6e08b12af2340f7a13c Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Thu, 7 Aug 2025 13:48:03 -0500
Subject: [PATCH 45/72] Add more artifacts to the skip list (#732)
I noticed we were fetching these but... we shouldn't be :)
---
src/github.rs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/github.rs b/src/github.rs
index 676104f..5db2247 100644
--- a/src/github.rs
+++ b/src/github.rs
@@ -259,6 +259,9 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<()
for artifact in artifacts {
if matches!(artifact.name.as_str(), "pythonbuild" | "toolchain")
|| artifact.name.contains("install-only")
+ || artifact.name.contains("dockerbuild")
+ || artifact.name.contains("crate-")
+ || artifact.name.contains("image-")
{
continue;
}
From 51d355fb9d71999eb9ba5269bf1e9718d57c857a Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Fri, 8 Aug 2025 12:44:20 -0400
Subject: [PATCH 46/72] Build libtcl, libtk, and _tkinter as shared objects,
and remove Tix (#676)
Several important third-party packages, including matplotlib in its
tkagg backend and Pillow, use tkinter as a way of locating libtcl and
libtk and making direct C API calls to those libraries. For more
details, see the analysis in
https://github.com/astral-sh/python-build-standalone/issues/129#issuecomment-3016267363
To make these packages work, we need to expose the full libtcl and
libtk dynamic symbol ABI; we can't just statically link them into our
own binary. It seems most robust to also expose these as separate
libraries under their usual filenames to match the behavior of other
Python distributions.
Build shared libraries for the _tkinter module and for libtcl and libtk,
and set up rpaths so we find our copies of them. libX11 continues to be
statically linked, but it's linked into libtk. Just as with the build of
Python itself, use --exclude-libs=ALL to prevent the dependencies'
symbols from being exported.
Stop building Tix because it's broken (#723) and it would need to be
changed to dynamic linking.
Configure libX11 with --disable-loadable-xcursor to fix #146, which I
ran into while running tests.
Add zlib as a build-dep of Tcl/Tk so that they can statically link
libz.a. I think we were previously picking up the zlib headers from the
OS, which wasn't a problem when libtcl and libtk were static libraries -
they got linked into CPython itself which also linked zlib.a. But now
libtcl.so and libtk.so need zlib.a.
Fixes #129
Fixes #533
---
Cargo.toml | 2 +-
cpython-unix/Makefile | 17 +++---
cpython-unix/build-cpython.sh | 23 +++++++--
cpython-unix/build-libX11.sh | 5 ++
cpython-unix/build-main.py | 2 +-
cpython-unix/build-tcl.sh | 28 +++++++---
cpython-unix/build-tk.sh | 40 +++++++++-----
cpython-unix/build.py | 62 ++--------------------
cpython-unix/extension-modules.yml | 26 ++--------
cpython-unix/targets.yml | 16 ------
docs/distributions.rst | 4 +-
docs/quirks.rst | 23 +++++----
docs/status.rst | 2 +-
pythonbuild/cpython.py | 13 ++++-
src/validation.rs | 83 ++++++++++++++++++++++++++----
15 files changed, 189 insertions(+), 157 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index b74eeb6..beca9e8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,7 +2,7 @@
name = "pythonbuild"
version = "0.1.0"
authors = ["Gregory Szorc "]
-edition = "2021"
+edition = "2024"
[dependencies]
anyhow = "1.0.80"
diff --git a/cpython-unix/Makefile b/cpython-unix/Makefile
index 40c34a2..7e56414 100644
--- a/cpython-unix/Makefile
+++ b/cpython-unix/Makefile
@@ -192,18 +192,14 @@ $(OUTDIR)/patchelf-$(PATCHELF_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPEN
$(OUTDIR)/sqlite-$(SQLITE_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-sqlite.sh
$(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) sqlite
-$(OUTDIR)/tcl-$(TCL_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-tcl.sh
- $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) tcl
-
-TIX_DEPENDS = \
- $(HERE)/build-tix.sh \
- $(OUTDIR)/tcl-$(TCL_VERSION)-$(PACKAGE_SUFFIX).tar \
- $(OUTDIR)/tk-$(TK_VERSION)-$(PACKAGE_SUFFIX).tar \
- $(if $(NEED_LIBX11),$(OUTDIR)/libX11-$(LIBX11_VERSION)-$(PACKAGE_SUFFIX).tar) \
+TCL_DEPENDS = \
+ $(PYTHON_DEP_DEPENDS) \
+ $(HERE)/build-tcl.sh \
+ $(OUTDIR)/zlib-$(ZLIB_VERSION)-$(PACKAGE_SUFFIX).tar \
$(NULL)
-$(OUTDIR)/tix-$(TIX_VERSION)-$(PACKAGE_SUFFIX).tar: $(TIX_DEPENDS)
- $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) tix
+$(OUTDIR)/tcl-$(TCL_VERSION)-$(PACKAGE_SUFFIX).tar: $(TCL_DEPENDS)
+ $(RUN_BUILD) --docker-image $(DOCKER_IMAGE_BUILD) tcl
TK_DEPENDS = \
$(HOST_PYTHON_DEPENDS) \
@@ -271,7 +267,6 @@ PYTHON_DEPENDS_$(1) := \
$$(if $$(NEED_SQLITE),$$(OUTDIR)/sqlite-$$(SQLITE_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(if $$(NEED_TCL),$$(OUTDIR)/tcl-$$(TCL_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(if $$(NEED_TK),$$(OUTDIR)/tk-$$(TK_VERSION)-$$(PACKAGE_SUFFIX).tar) \
- $$(if $$(NEED_TIX),$$(OUTDIR)/tix-$$(TIX_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(if $$(NEED_UUID),$$(OUTDIR)/uuid-$$(UUID_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(if $$(NEED_XZ),$$(OUTDIR)/xz-$$(XZ_VERSION)-$$(PACKAGE_SUFFIX).tar) \
$$(if $$(NEED_ZLIB),$$(OUTDIR)/zlib-$$(ZLIB_VERSION)-$$(PACKAGE_SUFFIX).tar) \
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index 04dab67..658395a 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -44,7 +44,7 @@ sed "${sed_args[@]}" "s|/tools/host|${TOOLS_PATH}/host|g" ${TOOLS_PATH}/host/sha
# We force linking of external static libraries by removing the shared
# libraries. This is hacky. But we're building in a temporary container
# and it gets the job done.
-find ${TOOLS_PATH}/deps -name '*.so*' -exec rm {} \;
+find ${TOOLS_PATH}/deps -name '*.so*' -a \! \( -name 'libtcl*.so*' -or -name 'libtk*.so*' \) -exec rm {} \;
tar -xf Python-${PYTHON_VERSION}.tar.xz
@@ -693,6 +693,8 @@ if [ "${PYBUILD_SHARED}" = "1" ]; then
${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}
# Python's build system doesn't make this file writable.
+ # TODO(geofft): @executable_path/ is a weird choice here, who is
+ # relying on it? Should probably be @loader_path.
chmod 755 ${ROOT}/out/python/install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}
install_name_tool \
-change /install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} @executable_path/${LIBPYTHON_SHARED_LIBRARY_BASENAME} \
@@ -711,6 +713,13 @@ if [ "${PYBUILD_SHARED}" = "1" ]; then
-change /install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} @executable_path/../lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} \
${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}
fi
+
+ # At the moment, python3 and libpython don't have shared-library
+ # dependencies, but at some point we will want to run this for
+ # them too.
+ for module in ${ROOT}/out/python/install/lib/python*/lib-dynload/*.so; do
+ install_name_tool -add_rpath @loader_path/../.. "$module"
+ done
else # (not macos)
LIBPYTHON_SHARED_LIBRARY_BASENAME=libpython${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}.so.1.0
LIBPYTHON_SHARED_LIBRARY=${ROOT}/out/python/install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}
@@ -1232,16 +1241,20 @@ fi
rm -f ${ROOT}/out/python/build/lib/{libdb-6.0,libxcb-*,libX11-xcb}.a
if [ -d "${TOOLS_PATH}/deps/lib/tcl8" ]; then
- # Copy tcl/tk/tix resources needed by tkinter.
+ # Copy tcl/tk resources needed by tkinter.
mkdir ${ROOT}/out/python/install/lib/tcl
# Keep this list in sync with tcl_library_paths.
for source in ${TOOLS_PATH}/deps/lib/{itcl4.2.4,tcl8,tcl8.6,thread2.8.9,tk8.6}; do
cp -av $source ${ROOT}/out/python/install/lib/
done
- if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then
- cp -av ${TOOLS_PATH}/deps/lib/Tix8.4.3 ${ROOT}/out/python/install/lib/
- fi
+ (
+ shopt -s nullglob
+ dylibs=(${TOOLS_PATH}/deps/lib/lib*.dylib ${TOOLS_PATH}/deps/lib/lib*.so)
+ if [ "${#dylibs[@]}" -gt 0 ]; then
+ cp -av "${dylibs[@]}" ${ROOT}/out/python/install/lib/
+ fi
+ )
fi
# Copy the terminfo database if present.
diff --git a/cpython-unix/build-libX11.sh b/cpython-unix/build-libX11.sh
index bb45028..9be17ee 100755
--- a/cpython-unix/build-libX11.sh
+++ b/cpython-unix/build-libX11.sh
@@ -99,6 +99,11 @@ if [ -n "${CROSS_COMPILING}" ]; then
esac
fi
+# Avoid dlopen("libXcursor.so.1") from the OS, which can go horribly wrong. We
+# might not need to avoid this if we switch to shipping X11 as shared
+# libraries, and ideally if we ship libXcursor ourselves.
+EXTRA_FLAGS="${EXTRA_FLAGS} --disable-loadable-xcursor"
+
# CC_FOR_BUILD is here because configure doesn't look for `clang` when
# cross-compiling. So we force it.
CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC -I/tools/deps/include" \
diff --git a/cpython-unix/build-main.py b/cpython-unix/build-main.py
index 7a7d08b..23d473e 100755
--- a/cpython-unix/build-main.py
+++ b/cpython-unix/build-main.py
@@ -182,7 +182,7 @@ def main():
# because we can get some speedup from parallel operations. But we also don't
# share a make job server with each build. So if we didn't limit the
# parallelism we could easily oversaturate the CPU. Higher levels of
- # parallelism don't result in meaningful build speedups because tk/tix has
+ # parallelism don't result in meaningful build speedups because tk has
# a long, serial dependency chain that can't be built in parallel.
parallelism = min(1 if args.serial else 4, multiprocessing.cpu_count())
diff --git a/cpython-unix/build-tcl.sh b/cpython-unix/build-tcl.sh
index 43a4a6a..bfbc22f 100755
--- a/cpython-unix/build-tcl.sh
+++ b/cpython-unix/build-tcl.sh
@@ -7,6 +7,12 @@ set -ex
ROOT=`pwd`
+# Force linking to static libraries from our dependencies.
+# TODO(geofft): This is copied from build-cpython.sh. Really this should
+# be done at the end of the build of each dependency, rather than before
+# the build of each consumer.
+find ${TOOLS_PATH}/deps -name '*.so*' -exec rm {} \;
+
export PATH=${TOOLS_PATH}/${TOOLCHAIN}/bin:${TOOLS_PATH}/host/bin:$PATH
export PKG_CONFIG_PATH=${TOOLS_PATH}/deps/share/pkgconfig:${TOOLS_PATH}/deps/lib/pkgconfig
@@ -20,9 +26,8 @@ if [ -n "${STATIC}" ]; then
# `checking whether musl-clang accepts -g...` fails with a duplicate definition error
TARGET_TRIPLE="$(echo "${TARGET_TRIPLE}" | sed -e 's/-unknown-linux-musl/-unknown-linux-gnu/g')"
fi
-fi
-patch -p1 << 'EOF'
+ patch -p1 << 'EOF'
diff --git a/unix/Makefile.in b/unix/Makefile.in
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -36,6 +41,7 @@ diff --git a/unix/Makefile.in b/unix/Makefile.in
fi; \
fi; \
EOF
+fi
# Remove packages we don't care about and can pull in unwanted symbols.
rm -rf pkgs/sqlite* pkgs/tdbc*
@@ -43,17 +49,23 @@ rm -rf pkgs/sqlite* pkgs/tdbc*
pushd unix
CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC -I${TOOLS_PATH}/deps/include"
+LDFLAGS="${EXTRA_TARGET_CFLAGS} -L${TOOLS_PATH}/deps/lib"
+if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then
+ LDFLAGS="${LDFLAGS} -Wl,--exclude-libs,ALL"
+fi
-CFLAGS="${CFLAGS}" CPPFLAGS="${CFLAGS}" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure \
+CFLAGS="${CFLAGS}" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" ./configure \
--build=${BUILD_TRIPLE} \
--host=${TARGET_TRIPLE} \
--prefix=/tools/deps \
- --enable-shared=no \
+ --enable-shared"${STATIC:+=no}" \
--enable-threads
-make -j ${NUM_CPUS}
-make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out
+make -j ${NUM_CPUS} DYLIB_INSTALL_DIR=@rpath
+make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out DYLIB_INSTALL_DIR=@rpath
make -j ${NUM_CPUS} install-private-headers DESTDIR=${ROOT}/out
-# For some reason libtcl*.a have weird permissions. Fix that.
-chmod 644 ${ROOT}/out/tools/deps/lib/libtcl*.a
+if [ -n "${STATIC}" ]; then
+ # For some reason libtcl*.a have weird permissions. Fix that.
+ chmod 644 ${ROOT}/out/tools/deps/lib/libtcl*.a
+fi
diff --git a/cpython-unix/build-tk.sh b/cpython-unix/build-tk.sh
index 2769a63..bd936c8 100755
--- a/cpython-unix/build-tk.sh
+++ b/cpython-unix/build-tk.sh
@@ -7,6 +7,12 @@ set -ex
ROOT=`pwd`
+# Force linking to static libraries from our dependencies.
+# TODO(geofft): This is copied from build-cpython.sh. Really this should
+# be done at the end of the build of each dependency, rather than before
+# the build of each consumer.
+find ${TOOLS_PATH}/deps -name '*.so*' -exec rm {} \;
+
export PATH=${TOOLS_PATH}/deps/bin:${TOOLS_PATH}/${TOOLCHAIN}/bin:${TOOLS_PATH}/host/bin:$PATH
export PKG_CONFIG_PATH=${TOOLS_PATH}/deps/share/pkgconfig:${TOOLS_PATH}/deps/lib/pkgconfig
@@ -23,6 +29,7 @@ if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then
LDFLAGS="-L${TOOLS_PATH}/deps/lib"
EXTRA_CONFIGURE_FLAGS="--enable-aqua=yes --without-x"
else
+ LDFLAGS="${LDFLAGS} -Wl,--exclude-libs,ALL"
EXTRA_CONFIGURE_FLAGS="--x-includes=${TOOLS_PATH}/deps/include --x-libraries=${TOOLS_PATH}/deps/lib"
fi
@@ -31,29 +38,38 @@ CFLAGS="${CFLAGS}" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" ./configure \
--host=${TARGET_TRIPLE} \
--prefix=/tools/deps \
--with-tcl=${TOOLS_PATH}/deps/lib \
- --enable-shared=no \
+ --enable-shared"${STATIC:+=no}" \
--enable-threads \
${EXTRA_CONFIGURE_FLAGS}
# Remove wish, since we don't need it.
-if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then
- sed -i 's/all: binaries libraries doc/all: libraries/' Makefile
- sed -i 's/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE) ${WISH_EXE}/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE)/' Makefile
+if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then
+ sed_args=(-i '' -e)
+else
+ sed_args=(-i)
fi
+sed "${sed_args[@]}" 's/all: binaries libraries doc/all: libraries/' Makefile
+sed "${sed_args[@]}" 's/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE) ${WISH_EXE}/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE)/' Makefile
-# For some reason musl isn't link libXau and libxcb. So we hack the Makefile
-# to do what we want.
-if [ "${CC}" = "musl-clang" ]; then
- sed -i 's/-ldl -lpthread /-ldl -lpthread -lXau -lxcb/' tkConfig.sh
- sed -i 's/-lpthread $(X11_LIB_SWITCHES) -ldl -lpthread/-lpthread $(X11_LIB_SWITCHES) -ldl -lpthread -lXau -lxcb/' Makefile
+# We are statically linking libX11, and static libraries do not carry
+# information about dependencies. pkg-config --static does, but Tcl/Tk's
+# build system apparently is too old for that. So we need to manually
+# inform the build process that libX11.a needs libxcb.a and libXau.a.
+# Note that the order is significant, for static libraries: X11 requires
+# xcb, which requires Xau.
+MAKE_VARS=(DYLIB_INSTALL_DIR=@rpath)
+if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then
+ MAKE_VARS+=(X11_LIB_SWITCHES="-lX11 -lxcb -lXau")
fi
-make -j ${NUM_CPUS}
+make -j ${NUM_CPUS} "${MAKE_VARS[@]}"
touch wish
-make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out
+make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out "${MAKE_VARS[@]}"
make -j ${NUM_CPUS} install-private-headers DESTDIR=${ROOT}/out
# For some reason libtk*.a have weird permissions. Fix that.
-chmod 644 /${ROOT}/out/tools/deps/lib/libtk*.a
+if [ -n "${STATIC}" ]; then
+ chmod 644 /${ROOT}/out/tools/deps/lib/libtk*.a
+fi
rm ${ROOT}/out/tools/deps/bin/wish*
diff --git a/cpython-unix/build.py b/cpython-unix/build.py
index b35d172..ea44c29 100755
--- a/cpython-unix/build.py
+++ b/cpython-unix/build.py
@@ -379,48 +379,6 @@ def build_libedit(
build_env.get_tools_archive(dest_archive, "deps")
-def build_tix(
- settings, client, image, host_platform, target_triple, build_options, dest_archive
-):
- tcl_archive = download_entry("tcl", DOWNLOADS_PATH)
- tk_archive = download_entry("tk", DOWNLOADS_PATH)
- tix_archive = download_entry("tix", DOWNLOADS_PATH)
-
- with build_environment(client, image) as build_env:
- if settings.get("needs_toolchain"):
- build_env.install_toolchain(
- BUILD,
- host_platform,
- target_triple,
- binutils=install_binutils(host_platform),
- clang=True,
- musl="musl" in target_triple,
- static="static" in build_options,
- )
-
- depends = {"tcl", "tk"}
- if not host_platform.startswith("macos_"):
- depends |= {"libX11", "xorgproto"}
-
- for p in sorted(depends):
- build_env.install_artifact_archive(BUILD, p, target_triple, build_options)
-
- for p in (tcl_archive, tk_archive, tix_archive, SUPPORT / "build-tix.sh"):
- build_env.copy_file(p)
-
- env = {
- "TOOLCHAIN": "clang-%s" % host_platform,
- "TCL_VERSION": DOWNLOADS["tcl"]["version"],
- "TIX_VERSION": DOWNLOADS["tix"]["version"],
- "TK_VERSION": DOWNLOADS["tk"]["version"],
- }
-
- add_target_env(env, host_platform, target_triple, build_env)
-
- build_env.run("build-tix.sh", environment=env)
- build_env.get_tools_archive(dest_archive, "deps")
-
-
def build_cpython_host(
client,
image,
@@ -946,9 +904,6 @@ def build_cpython(
"tk8.6",
]
- if "-apple" not in target_triple:
- python_info["tcl_library_paths"].append("Tix8.4.3")
-
if "-apple" in target_triple:
python_info["apple_sdk_platform"] = env["APPLE_SDK_PLATFORM"]
python_info["apple_sdk_version"] = env["APPLE_SDK_VERSION"]
@@ -1166,6 +1121,9 @@ def main():
"zstd",
):
tools_path = "host" if action in ("m4", "patchelf") else "deps"
+ extra_archives = {
+ "tcl": {"zlib"},
+ }.get(action)
simple_build(
settings,
@@ -1176,6 +1134,7 @@ def main():
target_triple=target_triple,
build_options=build_options,
dest_archive=dest_archive,
+ extra_archives=extra_archives,
tools_path=tools_path,
)
@@ -1239,19 +1198,8 @@ def main():
python_host_version=python_host_version,
)
- elif action == "tix":
- build_tix(
- settings,
- client,
- get_image(client, ROOT, BUILD, docker_image, host_platform),
- host_platform=host_platform,
- target_triple=target_triple,
- build_options=build_options,
- dest_archive=dest_archive,
- )
-
elif action == "tk":
- extra_archives = {"tcl"}
+ extra_archives = {"tcl", "zlib"}
if not host_platform.startswith("macos_"):
extra_archives |= {
"libX11",
diff --git a/cpython-unix/extension-modules.yml b/cpython-unix/extension-modules.yml
index c069ca1..a3b750d 100644
--- a/cpython-unix/extension-modules.yml
+++ b/cpython-unix/extension-modules.yml
@@ -673,45 +673,27 @@ _tkinter:
sources:
- _tkinter.c
- tkappinit.c
- # TODO consider adding WITH_TIX, as Modules/Setup seems to recommend it. This also
- # initializes tix at init time, which seems desirable.
defines:
- WITH_APPINIT
includes-deps:
- include/X11
+ build-mode: shared
links:
- tcl8.6
- tk8.6
-
- # Without -ObjC, we get a crash: -[TKApplication tkProcessEvent:]: unrecognized selector sent to instance.
- # See also https://core.tcl-lang.org/tk/tktview/85f316beb15108ac43b03fa6c8608e31f3ae5f92.
- # This is apparently an issue with static linking Objective-C binaries.
- linker-args:
- - args: ["-ObjC"]
- targets:
- - .*-apple-darwin
links-conditional:
- name: X11
targets:
- .*-unknown-linux-.*
+ build-mode: static
- name: xcb
targets:
- .*-unknown-linux-.*
+ build-mode: static
- name: Xau
targets:
- .*-unknown-linux-.*
- # Many of these are dependencies of libtcl and libtk.
- frameworks:
- - AppKit
- - ApplicationServices
- - Carbon
- - Cocoa
- - CoreFoundation
- - CoreServices
- - CoreGraphics
- - IOKit
- - QuartzCore
- - UniformTypeIdentifiers
+ build-mode: static
_tokenize:
minimum-python-version: "3.11"
diff --git a/cpython-unix/targets.yml b/cpython-unix/targets.yml
index 33db80c..d0ef4a7 100644
--- a/cpython-unix/targets.yml
+++ b/cpython-unix/targets.yml
@@ -195,7 +195,6 @@ aarch64-unknown-linux-gnu:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -285,7 +284,6 @@ armv7-unknown-linux-gnueabi:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -327,7 +325,6 @@ armv7-unknown-linux-gnueabihf:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -369,7 +366,6 @@ mips-unknown-linux-gnu:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -411,7 +407,6 @@ mipsel-unknown-linux-gnu:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -453,7 +448,6 @@ ppc64le-unknown-linux-gnu:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -495,7 +489,6 @@ riscv64-unknown-linux-gnu:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -537,7 +530,6 @@ s390x-unknown-linux-gnu:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -812,7 +804,6 @@ x86_64-unknown-linux-gnu:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -860,7 +851,6 @@ x86_64_v2-unknown-linux-gnu:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -908,7 +898,6 @@ x86_64_v3-unknown-linux-gnu:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -956,7 +945,6 @@ x86_64_v4-unknown-linux-gnu:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -1002,7 +990,6 @@ x86_64-unknown-linux-musl:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -1048,7 +1035,6 @@ x86_64_v2-unknown-linux-musl:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -1094,7 +1080,6 @@ x86_64_v3-unknown-linux-musl:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
@@ -1140,7 +1125,6 @@ x86_64_v4-unknown-linux-musl:
- sqlite
- tcl
- tk
- - tix
- uuid
- xorgproto
- xz
diff --git a/docs/distributions.rst b/docs/distributions.rst
index 3dd6125..9e4cf83 100644
--- a/docs/distributions.rst
+++ b/docs/distributions.rst
@@ -388,8 +388,8 @@ license_path
tcl_library_path
Relative path to location of tcl library files. The path should be a
directory tree containing tcl files to support the tkinter extension.
- This will include a subset of the library files provided by the tcl, tk,
- and tix packages.
+ This will include a subset of the library files provided by the tcl
+ and tk packages.
This points to the root directory containing tcl resources. Actual
tcl resources are in sub-directories underneath, as identified by
diff --git a/docs/quirks.rst b/docs/quirks.rst
index 8900cd6..f24886a 100644
--- a/docs/quirks.rst
+++ b/docs/quirks.rst
@@ -71,18 +71,21 @@ ncurses/libedit/readline are loaded.
.. _quirk_macos_no_tix:
-No tix on macOS
-===============
+No tix on UNIX
+==============
+
+Tix is an old widget library for Tcl/Tk. Python previously had a wrapper
+for it in ``tkinter.tix``, but it was deprecated in Python 3.6 (the
+recommendation is to use ``tkinter.ttk``) and removed in Python 3.13.
-macOS distributions do not contain tix tcl support files. This means that
-``tkinter.tix`` module functionality will likely break at run-time. The
-module will import fine. But attempting to instantiate a ``tkinter.tix.Tk``
-instance or otherwise attempt to run tix tcl files will result in a run-time
-error.
+The macOS and Linux distributions from this project do not build and
+ship Tix, even for Python versions 3.12 and below.
-``tkinter.tix`` has been deprecated since Python 3.6 and the official Python
-macOS installers do not ship the tix support files. So this project behaves
-similarly to the official CPython distributions.
+We had previously attempted to ship Tix support on Linux, but it was
+broken and nobody reported an issue about it. The macOS distributions
+from this project never shipped support for Tix. The official Python.org
+macOS installers and Apple's build of Python do not ship support for
+Tix, either, so this project behaves similarly to those distributions.
.. _quirk_windows_no_pip:
diff --git a/docs/status.rst b/docs/status.rst
index ef172e0..cd50e07 100644
--- a/docs/status.rst
+++ b/docs/status.rst
@@ -285,7 +285,7 @@ test_spwd
test_startfile
object has no attribute 'startfile'
test_tix
- cannot run without OS X gui process
+ tix is not built by this project
test_tk
cannot run without OS X gui process
test_ttk_guionly
diff --git a/pythonbuild/cpython.py b/pythonbuild/cpython.py
index c52f7ce..bd7213b 100644
--- a/pythonbuild/cpython.py
+++ b/pythonbuild/cpython.py
@@ -69,6 +69,7 @@
"properties": {
"name": {"type": "string"},
"targets": {"type": "array", "items": {"type": "string"}},
+ "build-mode": {"type": "string"},
},
"additionalProperties": False,
},
@@ -535,7 +536,17 @@ def derive_setup_local(
python_version, entry.get("maximum-python-version", "100.0")
)
- if target_match and (python_min_match and python_max_match):
+ if build_mode := entry.get("build-mode"):
+ build_mode_match = section == build_mode
+ else:
+ build_mode_match = True
+
+ if (
+ target_match
+ and python_min_match
+ and python_max_match
+ and build_mode_match
+ ):
if source := entry.get("source"):
line += f" {source}"
for source in entry.get("sources", []):
diff --git a/src/validation.rs b/src/validation.rs
index b0ffb53..3b1ef5c 100644
--- a/src/validation.rs
+++ b/src/validation.rs
@@ -9,7 +9,7 @@ use {
normalize_path::NormalizePath,
object::{
elf::{
- FileHeader32, FileHeader64, ET_DYN, ET_EXEC, STB_GLOBAL, STB_WEAK, STV_DEFAULT,
+ FileHeader32, FileHeader64, ET_DYN, ET_EXEC, SHN_UNDEF, STB_GLOBAL, STB_WEAK, STV_DEFAULT,
STV_HIDDEN,
},
macho::{MachHeader32, MachHeader64, MH_OBJECT, MH_TWOLEVEL},
@@ -265,6 +265,25 @@ static ELF_ALLOWED_LIBRARIES_BY_TRIPLE: Lazy>> =
+ Lazy::new(|| {
+ [
+ (
+ // libcrypt is provided by the system, but only on older distros.
+ "_crypt",
+ vec!["libcrypt.so.1"],
+ ),
+ (
+ // libtcl and libtk are shipped in our distribution.
+ "_tkinter",
+ vec!["libtcl8.6.so", "libtk8.6.so"],
+ ),
+ ]
+ .iter()
+ .cloned()
+ .collect()
+ });
+
static DARWIN_ALLOWED_DYLIBS: Lazy> = Lazy::new(|| {
[
MachOAllowedDylib {
@@ -501,6 +520,29 @@ static IOS_ALLOWED_DYLIBS: Lazy> = Lazy::new(|| {
.to_vec()
});
+static ALLOWED_DYLIBS_BY_MODULE: Lazy>> =
+ Lazy::new(|| {
+ [(
+ // libtcl and libtk are shipped in our distribution.
+ "_tkinter",
+ vec![
+ MachOAllowedDylib {
+ name: "@rpath/libtcl8.6.dylib".to_string(),
+ max_compatibility_version: "8.6.0".try_into().unwrap(),
+ required: true,
+ },
+ MachOAllowedDylib {
+ name: "@rpath/libtk8.6.dylib".to_string(),
+ max_compatibility_version: "8.6.0".try_into().unwrap(),
+ required: true,
+ },
+ ],
+ )]
+ .iter()
+ .cloned()
+ .collect()
+ });
+
static PLATFORM_TAG_BY_TRIPLE: Lazy> = Lazy::new(|| {
[
("aarch64-apple-darwin", "macosx-11.0-arm64"),
@@ -544,9 +586,12 @@ const ELF_BANNED_SYMBOLS: &[&str] = &[
/// We use this list to spot test behavior of symbols belonging to dependency packages.
/// The list is obviously not complete.
const DEPENDENCY_PACKAGE_SYMBOLS: &[&str] = &[
- // libX11
- "XClearWindow",
- "XFlush",
+ /* TODO(geofft): Tk provides these as no-op stubs on macOS, make it
+ * stop doing that so we can reenable the check
+ * // libX11
+ * "XClearWindow",
+ * "XFlush",
+ */
// OpenSSL
"BIO_ADDR_new",
"BN_new",
@@ -591,6 +636,11 @@ const DEPENDENCY_PACKAGE_SYMBOLS: &[&str] = &[
// liblzma
"lzma_index_init",
"lzma_stream_encoder",
+];
+
+// TODO(geofft): Conditionally prohibit these exported symbols
+// everywhere except libtcl and libtk. This should be a hashmap
+const _DEPENDENCY_PACKAGE_SYMBOLS_BUNDLED: &[&str] = &[
// tcl
"Tcl_Alloc",
"Tcl_ChannelName",
@@ -822,7 +872,7 @@ const GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13: &[&str] = &["_msi"];
const GLOBAL_EXTENSIONS_WINDOWS_NO_STATIC: &[&str] = &["_testinternalcapi", "_tkinter"];
/// Extension modules that should be built as shared libraries.
-const SHARED_LIBRARY_EXTENSIONS: &[&str] = &["_crypt"];
+const SHARED_LIBRARY_EXTENSIONS: &[&str] = &["_crypt", "_tkinter"];
const PYTHON_VERIFICATIONS: &str = include_str!("verify_distribution.py");
@@ -967,11 +1017,13 @@ fn validate_elf>(
allowed_libraries.push("libc.so".to_string());
}
- // Allow the _crypt extension module - and only it - to link against libcrypt,
- // which is no longer universally present in Linux distros.
+ // Allow certain extension modules to link against shared libraries
+ // (either from the system or from our distribution).
if let Some(filename) = path.file_name() {
- if filename.to_string_lossy().starts_with("_crypt") {
- allowed_libraries.push("libcrypt.so.1".to_string());
+ if let Some((module, _)) = filename.to_string_lossy().split_once(".cpython-") {
+ if let Some(extra) = ELF_ALLOWED_LIBRARIES_BY_MODULE.get(module) {
+ allowed_libraries.extend(extra.iter().map(|x| x.to_string()));
+ }
}
}
@@ -1109,6 +1161,7 @@ fn validate_elf>(
// to prevent them from being exported.
if DEPENDENCY_PACKAGE_SYMBOLS.contains(&name.as_ref())
&& matches!(symbol.st_bind(), STB_GLOBAL | STB_WEAK)
+ && symbol.st_shndx(endian) != SHN_UNDEF
&& symbol.st_visibility() != STV_HIDDEN
{
context.errors.push(format!(
@@ -1124,6 +1177,7 @@ fn validate_elf>(
if filename.starts_with("libpython")
&& filename.ends_with(".so.1.0")
&& matches!(symbol.st_bind(), STB_GLOBAL | STB_WEAK)
+ && symbol.st_shndx(endian) != SHN_UNDEF
&& symbol.st_visibility() == STV_DEFAULT
{
context.libpython_exported_symbols.insert(name.to_string());
@@ -1225,7 +1279,16 @@ fn validate_macho>(
dylib_names.push(lib.clone());
- let allowed = allowed_dylibs_for_triple(target_triple);
+ let mut allowed = allowed_dylibs_for_triple(target_triple);
+ // Allow certain extension modules to link against shared libraries
+ // (either from the system or from our distribution).
+ if let Some(filename) = path.file_name() {
+ if let Some((module, _)) = filename.to_string_lossy().split_once(".cpython-") {
+ if let Some(extra) = ALLOWED_DYLIBS_BY_MODULE.get(module) {
+ allowed.extend(extra.clone());
+ }
+ }
+ }
if let Some(entry) = allowed.iter().find(|l| l.name == lib) {
let load_version =
From 277c82e81b43930c0fa75ead052a39bbe465b2a0 Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Thu, 14 Aug 2025 07:31:34 -0700
Subject: [PATCH 47/72] Build _ctypes_test as a shared module (fixes #721)
(#747)
---
cpython-unix/extension-modules.yml | 1 +
src/validation.rs | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/cpython-unix/extension-modules.yml b/cpython-unix/extension-modules.yml
index a3b750d..4f9acc0 100644
--- a/cpython-unix/extension-modules.yml
+++ b/cpython-unix/extension-modules.yml
@@ -145,6 +145,7 @@ _ctypes:
- dl
_ctypes_test:
+ build-mode: shared
sources:
- _ctypes/_ctypes_test.c
links:
diff --git a/src/validation.rs b/src/validation.rs
index 3b1ef5c..6d9b5db 100644
--- a/src/validation.rs
+++ b/src/validation.rs
@@ -649,6 +649,10 @@ const _DEPENDENCY_PACKAGE_SYMBOLS_BUNDLED: &[&str] = &[
"TkBindInit",
"TkCreateFrame",
"Tk_FreeGC",
+ // _ctypes_test module
+ "my_free",
+ "mystrdup",
+ "top",
];
const PYTHON_EXPORTED_SYMBOLS: &[&str] = &[
@@ -872,7 +876,7 @@ const GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13: &[&str] = &["_msi"];
const GLOBAL_EXTENSIONS_WINDOWS_NO_STATIC: &[&str] = &["_testinternalcapi", "_tkinter"];
/// Extension modules that should be built as shared libraries.
-const SHARED_LIBRARY_EXTENSIONS: &[&str] = &["_crypt", "_tkinter"];
+const SHARED_LIBRARY_EXTENSIONS: &[&str] = &["_crypt", "_ctypes_test", "_tkinter"];
const PYTHON_VERIFICATIONS: &str = include_str!("verify_distribution.py");
From d231d773f03a3ce756a987fddab40a5d90036f65 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Thu, 14 Aug 2025 10:58:42 -0500
Subject: [PATCH 48/72] Upgrade to 3.14.0rc2 (and temporarily use GitHub's
runners on Windows) (#754)
- **Bump CPython to 3.14.0rc2**
- **Drop the Depot Windows runner**
---
ci-runners.yaml | 5 -----
pythonbuild/downloads.py | 8 ++++----
2 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/ci-runners.yaml b/ci-runners.yaml
index dae6aab..849a254 100644
--- a/ci-runners.yaml
+++ b/ci-runners.yaml
@@ -25,11 +25,6 @@ macos-latest:
platform: darwin
free: true
-depot-windows-2022-8:
- arch: x86_64
- platform: windows
- free: false
-
windows-latest-large:
arch: x86_64
platform: windows
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index 7d80e34..d369d1b 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -82,10 +82,10 @@
"python_tag": "cp313",
},
"cpython-3.14": {
- "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0rc1.tar.xz",
- "size": 23661916,
- "sha256": "8707780ae9f19c5bf5b9f27827181ba11cdad7bb292ea49cad5424331e40ee8b",
- "version": "3.14.0rc1",
+ "url": "https://www.python.org/ftp/python/3.14.0/Python-3.14.0rc2.tar.xz",
+ "size": 23566140,
+ "sha256": "bc62854cf232345bd22c9091a68464e01e056c6473a3fffa84572c8a342da656",
+ "version": "3.14.0rc2",
"licenses": ["Python-2.0", "CNRI-Python"],
"license_file": "LICENSE.cpython.txt",
"python_tag": "cp314",
From 24fa3ddba3d0561de3ca5c64e1659c430b3fc779 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Thu, 14 Aug 2025 13:39:14 -0500
Subject: [PATCH 49/72] Bump Windows SDK to 10.0.26100.0 (#756)
The previous version is being dropped
- https://github.com/actions/runner-images/pull/12708
-
https://learn.microsoft.com/en-us/visualstudio/releases/2022/release-notes?tabs=allfeatures#17.14.11
---
cpython-windows/build.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cpython-windows/build.py b/cpython-windows/build.py
index 3b0c3b4..8f8cc43 100644
--- a/cpython-windows/build.py
+++ b/cpython-windows/build.py
@@ -1842,7 +1842,7 @@ def main() -> None:
)
parser.add_argument(
"--windows-sdk-version",
- default="10.0.20348.0",
+ default="10.0.26100.0",
help="Windows SDK version to build with",
)
From 1260d902fa132a2aa6c0652b51056cdd168a8a41 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Fri, 15 Aug 2025 09:00:08 -0500
Subject: [PATCH 50/72] Restore the Depot Windows runners (#757)
This reverts commit 6228086c4523ca1d3e77b5215cf5f280c4d3c21b following
#756
---
ci-runners.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/ci-runners.yaml b/ci-runners.yaml
index 849a254..dae6aab 100644
--- a/ci-runners.yaml
+++ b/ci-runners.yaml
@@ -25,6 +25,11 @@ macos-latest:
platform: darwin
free: true
+depot-windows-2022-8:
+ arch: x86_64
+ platform: windows
+ free: false
+
windows-latest-large:
arch: x86_64
platform: windows
From c0537632433ff4d5d7d8bfc1b4b6bc5d72970b7f Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Fri, 15 Aug 2025 19:00:34 -0500
Subject: [PATCH 51/72] Bump CPython to 3.13.7 (#759)
---
pythonbuild/downloads.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index d369d1b..4332d68 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -73,10 +73,10 @@
"python_tag": "cp312",
},
"cpython-3.13": {
- "url": "https://www.python.org/ftp/python/3.13.6/Python-3.13.6.tar.xz",
- "size": 22761268,
- "sha256": "17ba5508819d8736a14fbfc47d36e184946a877851b2e9c4b6c43acb44a3b104",
- "version": "3.13.6",
+ "url": "https://www.python.org/ftp/python/3.13.7/Python-3.13.7.tar.xz",
+ "size": 22769492,
+ "sha256": "5462f9099dfd30e238def83c71d91897d8caa5ff6ebc7a50f14d4802cdaaa79a",
+ "version": "3.13.7",
"licenses": ["Python-2.0", "CNRI-Python"],
"license_file": "LICENSE.cpython.txt",
"python_tag": "cp313",
From ce0f50af1b88bd897fcab922d87a204656a879bc Mon Sep 17 00:00:00 2001
From: Gregory Szorc
Date: Fri, 15 Aug 2025 17:21:09 -0700
Subject: [PATCH 52/72] Fix download statistics (#706)
`just download-stats*` are failing with an HTTP 504 Gateway Timeout on
GitHub's servers.
We can work around this by reducing the requested number of releases per
page.
As part of this, we adopt a 3rd party package for querying the GitHub
API because I was too lazy to implement pagination manually. Also, since
pagination is enabled, the counts reported by these commands are now
accurate and don't implicitly truncate at the most recent 10 releases.
Co-authored-by: Zanie Blue
---
pythonbuild/utils.py | 20 ++--
requirements.dev.in | 1 +
requirements.dev.txt | 251 ++++++++++++++++++++++++++++++++++++++--
requirements.in | 1 +
requirements.txt | 230 ++++++++++++++++++++++++++++++++++++-
requirements.win.txt | 266 +++++++++++++++++++++++++++++++++++++++----
6 files changed, 728 insertions(+), 41 deletions(-)
diff --git a/pythonbuild/utils.py b/pythonbuild/utils.py
index 0edc11d..f784dc1 100644
--- a/pythonbuild/utils.py
+++ b/pythonbuild/utils.py
@@ -23,6 +23,7 @@
import urllib.request
import zipfile
+import github
import yaml
import zstandard
@@ -653,21 +654,20 @@ def validate_python_json(info, extension_modules):
def release_download_statistics(mode="by_asset"):
- with urllib.request.urlopen(
- "https://api.github.com/repos/astral-sh/python-build-standalone/releases"
- ) as fh:
- data = json.load(fh)
-
by_tag = collections.Counter()
by_build = collections.Counter()
by_build_install_only = collections.Counter()
- for release in data:
- tag = release["tag_name"]
+ # Default paging settings time out. Reduce page size as a workaround.
+ gh = github.Github(per_page=5)
+
+ repo = gh.get_repo("astral-sh/python-build-standalone")
+ for release in repo.get_releases():
+ tag = release.tag_name
- for asset in release["assets"]:
- name = asset["name"]
- count = asset["download_count"]
+ for asset in release.assets:
+ name = asset.name
+ count = asset.download_count
by_tag[tag] += count
diff --git a/requirements.dev.in b/requirements.dev.in
index 2f64d57..b06a90a 100644
--- a/requirements.dev.in
+++ b/requirements.dev.in
@@ -2,6 +2,7 @@
ruff
mypy
+PyGithub
types-jsonschema
types-PyYAML
types-jinja2
diff --git a/requirements.dev.txt b/requirements.dev.txt
index b45edbc..3ab1146 100644
--- a/requirements.dev.txt
+++ b/requirements.dev.txt
@@ -13,6 +13,78 @@ certifi==2024.12.14 \
# via
# -r requirements.txt
# requests
+cffi==1.17.1 \
+ --hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \
+ --hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \
+ --hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \
+ --hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \
+ --hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \
+ --hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \
+ --hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \
+ --hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \
+ --hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \
+ --hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \
+ --hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \
+ --hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \
+ --hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \
+ --hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \
+ --hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \
+ --hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \
+ --hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \
+ --hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \
+ --hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \
+ --hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \
+ --hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \
+ --hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \
+ --hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \
+ --hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \
+ --hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \
+ --hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \
+ --hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \
+ --hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \
+ --hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \
+ --hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \
+ --hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \
+ --hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \
+ --hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \
+ --hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \
+ --hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \
+ --hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \
+ --hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \
+ --hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \
+ --hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \
+ --hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \
+ --hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \
+ --hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \
+ --hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \
+ --hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \
+ --hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \
+ --hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \
+ --hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \
+ --hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \
+ --hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \
+ --hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \
+ --hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \
+ --hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \
+ --hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \
+ --hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \
+ --hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \
+ --hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \
+ --hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \
+ --hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \
+ --hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \
+ --hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \
+ --hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \
+ --hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \
+ --hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \
+ --hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \
+ --hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \
+ --hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \
+ --hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b
+ # via
+ # -r requirements.txt
+ # cryptography
+ # pynacl
charset-normalizer==3.4.1 \
--hash=sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537 \
--hash=sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa \
@@ -109,6 +181,53 @@ charset-normalizer==3.4.1 \
# via
# -r requirements.txt
# requests
+cryptography==45.0.5 \
+ --hash=sha256:0027d566d65a38497bc37e0dd7c2f8ceda73597d2ac9ba93810204f56f52ebc7 \
+ --hash=sha256:101ee65078f6dd3e5a028d4f19c07ffa4dd22cce6a20eaa160f8b5219911e7d8 \
+ --hash=sha256:12e55281d993a793b0e883066f590c1ae1e802e3acb67f8b442e721e475e6463 \
+ --hash=sha256:14d96584701a887763384f3c47f0ca7c1cce322aa1c31172680eb596b890ec30 \
+ --hash=sha256:1e1da5accc0c750056c556a93c3e9cb828970206c68867712ca5805e46dc806f \
+ --hash=sha256:206210d03c1193f4e1ff681d22885181d47efa1ab3018766a7b32a7b3d6e6afd \
+ --hash=sha256:2089cc8f70a6e454601525e5bf2779e665d7865af002a5dec8d14e561002e135 \
+ --hash=sha256:3a264aae5f7fbb089dbc01e0242d3b67dffe3e6292e1f5182122bdf58e65215d \
+ --hash=sha256:3af26738f2db354aafe492fb3869e955b12b2ef2e16908c8b9cb928128d42c57 \
+ --hash=sha256:3fcfbefc4a7f332dece7272a88e410f611e79458fab97b5efe14e54fe476f4fd \
+ --hash=sha256:460f8c39ba66af7db0545a8c6f2eabcbc5a5528fc1cf6c3fa9a1e44cec33385e \
+ --hash=sha256:57c816dfbd1659a367831baca4b775b2a5b43c003daf52e9d57e1d30bc2e1b0e \
+ --hash=sha256:5aa1e32983d4443e310f726ee4b071ab7569f58eedfdd65e9675484a4eb67bd1 \
+ --hash=sha256:6ff8728d8d890b3dda5765276d1bc6fb099252915a2cd3aff960c4c195745dd0 \
+ --hash=sha256:7259038202a47fdecee7e62e0fd0b0738b6daa335354396c6ddebdbe1206af2a \
+ --hash=sha256:72e76caa004ab63accdf26023fccd1d087f6d90ec6048ff33ad0445abf7f605a \
+ --hash=sha256:7760c1c2e1a7084153a0f68fab76e754083b126a47d0117c9ed15e69e2103492 \
+ --hash=sha256:8c4a6ff8a30e9e3d38ac0539e9a9e02540ab3f827a3394f8852432f6b0ea152e \
+ --hash=sha256:9024beb59aca9d31d36fcdc1604dd9bbeed0a55bface9f1908df19178e2f116e \
+ --hash=sha256:90cb0a7bb35959f37e23303b7eed0a32280510030daba3f7fdfbb65defde6a97 \
+ --hash=sha256:91098f02ca81579c85f66df8a588c78f331ca19089763d733e34ad359f474174 \
+ --hash=sha256:926c3ea71a6043921050eaa639137e13dbe7b4ab25800932a8498364fc1abec9 \
+ --hash=sha256:982518cd64c54fcada9d7e5cf28eabd3ee76bd03ab18e08a48cad7e8b6f31b18 \
+ --hash=sha256:9b4cf6318915dccfe218e69bbec417fdd7c7185aa7aab139a2c0beb7468c89f0 \
+ --hash=sha256:ad0caded895a00261a5b4aa9af828baede54638754b51955a0ac75576b831b27 \
+ --hash=sha256:b85980d1e345fe769cfc57c57db2b59cff5464ee0c045d52c0df087e926fbe63 \
+ --hash=sha256:b8fa8b0a35a9982a3c60ec79905ba5bb090fc0b9addcfd3dc2dd04267e45f25e \
+ --hash=sha256:b9e38e0a83cd51e07f5a48ff9691cae95a79bea28fe4ded168a8e5c6c77e819d \
+ --hash=sha256:bd4c45986472694e5121084c6ebbd112aa919a25e783b87eb95953c9573906d6 \
+ --hash=sha256:be97d3a19c16a9be00edf79dca949c8fa7eff621763666a145f9f9535a5d7f42 \
+ --hash=sha256:c648025b6840fe62e57107e0a25f604db740e728bd67da4f6f060f03017d5097 \
+ --hash=sha256:d05a38884db2ba215218745f0781775806bde4f32e07b135348355fe8e4991d9 \
+ --hash=sha256:dd420e577921c8c2d31289536c386aaa30140b473835e97f83bc71ea9d2baf2d \
+ --hash=sha256:e357286c1b76403dd384d938f93c46b2b058ed4dfcdce64a770f0537ed3feb6f \
+ --hash=sha256:e6c00130ed423201c5bc5544c23359141660b07999ad82e34e7bb8f882bb78e0 \
+ --hash=sha256:e74d30ec9c7cb2f404af331d5b4099a9b322a8a6b25c4632755c8757345baac5 \
+ --hash=sha256:f3562c2f23c612f2e4a6964a61d942f891d29ee320edb62ff48ffb99f3de9ae8
+ # via
+ # -r requirements.txt
+ # pyjwt
+deprecated==1.2.18 \
+ --hash=sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d \
+ --hash=sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec
+ # via
+ # -r requirements.txt
+ # pygithub
docker==7.1.0 \
--hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \
--hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0
@@ -240,6 +359,38 @@ pathspec==0.12.1 \
--hash=sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 \
--hash=sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712
# via mypy
+pycparser==2.22 \
+ --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \
+ --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc
+ # via
+ # -r requirements.txt
+ # cffi
+pygithub==2.6.1 \
+ --hash=sha256:6f2fa6d076ccae475f9fc392cc6cdbd54db985d4f69b8833a28397de75ed6ca3 \
+ --hash=sha256:b5c035392991cca63959e9453286b41b54d83bf2de2daa7d7ff7e4312cebf3bf
+ # via
+ # -r requirements.dev.in
+ # -r requirements.txt
+pyjwt==2.10.1 \
+ --hash=sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953 \
+ --hash=sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb
+ # via
+ # -r requirements.txt
+ # pygithub
+pynacl==1.5.0 \
+ --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \
+ --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \
+ --hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \
+ --hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \
+ --hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \
+ --hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \
+ --hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \
+ --hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \
+ --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \
+ --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543
+ # via
+ # -r requirements.txt
+ # pygithub
pyyaml==6.0.2 \
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
--hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \
@@ -309,6 +460,7 @@ requests==2.32.3 \
# via
# -r requirements.txt
# docker
+ # pygithub
rpds-py==0.22.3 \
--hash=sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518 \
--hash=sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059 \
@@ -474,9 +626,7 @@ tomli==2.2.1 \
--hash=sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272 \
--hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \
--hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7
- # via
- # -r requirements.txt
- # mypy
+ # via -r requirements.txt
types-jinja2==2.11.9 \
--hash=sha256:60a1e21e8296979db32f9374d8a239af4cb541ff66447bb915d8ad398f9c63b2 \
--hash=sha256:dbdc74a40aba7aed520b7e4d89e8f0fe4286518494208b35123bcf084d4b8c81
@@ -493,17 +643,104 @@ types-pyyaml==6.0.12.20250516 \
--hash=sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530 \
--hash=sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba
# via -r requirements.dev.in
-typing-extensions==4.9.0 \
- --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \
- --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd
- # via mypy
+typing-extensions==4.14.1 \
+ --hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \
+ --hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76
+ # via
+ # -r requirements.txt
+ # mypy
+ # pygithub
urllib3==2.3.0 \
--hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \
--hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d
# via
# -r requirements.txt
# docker
+ # pygithub
# requests
+wrapt==1.17.2 \
+ --hash=sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f \
+ --hash=sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c \
+ --hash=sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a \
+ --hash=sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b \
+ --hash=sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555 \
+ --hash=sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c \
+ --hash=sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b \
+ --hash=sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6 \
+ --hash=sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8 \
+ --hash=sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662 \
+ --hash=sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061 \
+ --hash=sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998 \
+ --hash=sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb \
+ --hash=sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62 \
+ --hash=sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984 \
+ --hash=sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392 \
+ --hash=sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2 \
+ --hash=sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306 \
+ --hash=sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7 \
+ --hash=sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3 \
+ --hash=sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9 \
+ --hash=sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6 \
+ --hash=sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192 \
+ --hash=sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317 \
+ --hash=sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f \
+ --hash=sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda \
+ --hash=sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563 \
+ --hash=sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a \
+ --hash=sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f \
+ --hash=sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d \
+ --hash=sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9 \
+ --hash=sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8 \
+ --hash=sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82 \
+ --hash=sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9 \
+ --hash=sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845 \
+ --hash=sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82 \
+ --hash=sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125 \
+ --hash=sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504 \
+ --hash=sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b \
+ --hash=sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7 \
+ --hash=sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc \
+ --hash=sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6 \
+ --hash=sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40 \
+ --hash=sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a \
+ --hash=sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3 \
+ --hash=sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a \
+ --hash=sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72 \
+ --hash=sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681 \
+ --hash=sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438 \
+ --hash=sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae \
+ --hash=sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2 \
+ --hash=sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb \
+ --hash=sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5 \
+ --hash=sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a \
+ --hash=sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3 \
+ --hash=sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8 \
+ --hash=sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2 \
+ --hash=sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22 \
+ --hash=sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72 \
+ --hash=sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061 \
+ --hash=sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f \
+ --hash=sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9 \
+ --hash=sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04 \
+ --hash=sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98 \
+ --hash=sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9 \
+ --hash=sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f \
+ --hash=sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b \
+ --hash=sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925 \
+ --hash=sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6 \
+ --hash=sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0 \
+ --hash=sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9 \
+ --hash=sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c \
+ --hash=sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991 \
+ --hash=sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6 \
+ --hash=sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000 \
+ --hash=sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb \
+ --hash=sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119 \
+ --hash=sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b \
+ --hash=sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58
+ # via
+ # -r requirements.txt
+ # deprecated
zstandard==0.23.0 \
--hash=sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473 \
--hash=sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916 \
diff --git a/requirements.in b/requirements.in
index 0e9ae39..552e62d 100644
--- a/requirements.in
+++ b/requirements.in
@@ -1,6 +1,7 @@
docker
jinja2
jsonschema
+PyGithub
PyYAML
# Undeclared dependency in docker 5.0 package.
six
diff --git a/requirements.txt b/requirements.txt
index 2baa344..9ad29ed 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -10,6 +10,77 @@ certifi==2024.12.14 \
--hash=sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56 \
--hash=sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db
# via requests
+cffi==1.17.1 \
+ --hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \
+ --hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \
+ --hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \
+ --hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \
+ --hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \
+ --hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \
+ --hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \
+ --hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \
+ --hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \
+ --hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \
+ --hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \
+ --hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \
+ --hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \
+ --hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \
+ --hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \
+ --hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \
+ --hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \
+ --hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \
+ --hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \
+ --hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \
+ --hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \
+ --hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \
+ --hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \
+ --hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \
+ --hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \
+ --hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \
+ --hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \
+ --hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \
+ --hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \
+ --hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \
+ --hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \
+ --hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \
+ --hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \
+ --hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \
+ --hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \
+ --hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \
+ --hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \
+ --hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \
+ --hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \
+ --hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \
+ --hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \
+ --hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \
+ --hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \
+ --hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \
+ --hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \
+ --hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \
+ --hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \
+ --hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \
+ --hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \
+ --hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \
+ --hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \
+ --hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \
+ --hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \
+ --hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \
+ --hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \
+ --hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \
+ --hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \
+ --hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \
+ --hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \
+ --hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \
+ --hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \
+ --hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \
+ --hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \
+ --hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \
+ --hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \
+ --hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \
+ --hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b
+ # via
+ # cryptography
+ # pynacl
charset-normalizer==3.4.1 \
--hash=sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537 \
--hash=sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa \
@@ -104,6 +175,49 @@ charset-normalizer==3.4.1 \
--hash=sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00 \
--hash=sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616
# via requests
+cryptography==45.0.5 \
+ --hash=sha256:0027d566d65a38497bc37e0dd7c2f8ceda73597d2ac9ba93810204f56f52ebc7 \
+ --hash=sha256:101ee65078f6dd3e5a028d4f19c07ffa4dd22cce6a20eaa160f8b5219911e7d8 \
+ --hash=sha256:12e55281d993a793b0e883066f590c1ae1e802e3acb67f8b442e721e475e6463 \
+ --hash=sha256:14d96584701a887763384f3c47f0ca7c1cce322aa1c31172680eb596b890ec30 \
+ --hash=sha256:1e1da5accc0c750056c556a93c3e9cb828970206c68867712ca5805e46dc806f \
+ --hash=sha256:206210d03c1193f4e1ff681d22885181d47efa1ab3018766a7b32a7b3d6e6afd \
+ --hash=sha256:2089cc8f70a6e454601525e5bf2779e665d7865af002a5dec8d14e561002e135 \
+ --hash=sha256:3a264aae5f7fbb089dbc01e0242d3b67dffe3e6292e1f5182122bdf58e65215d \
+ --hash=sha256:3af26738f2db354aafe492fb3869e955b12b2ef2e16908c8b9cb928128d42c57 \
+ --hash=sha256:3fcfbefc4a7f332dece7272a88e410f611e79458fab97b5efe14e54fe476f4fd \
+ --hash=sha256:460f8c39ba66af7db0545a8c6f2eabcbc5a5528fc1cf6c3fa9a1e44cec33385e \
+ --hash=sha256:57c816dfbd1659a367831baca4b775b2a5b43c003daf52e9d57e1d30bc2e1b0e \
+ --hash=sha256:5aa1e32983d4443e310f726ee4b071ab7569f58eedfdd65e9675484a4eb67bd1 \
+ --hash=sha256:6ff8728d8d890b3dda5765276d1bc6fb099252915a2cd3aff960c4c195745dd0 \
+ --hash=sha256:7259038202a47fdecee7e62e0fd0b0738b6daa335354396c6ddebdbe1206af2a \
+ --hash=sha256:72e76caa004ab63accdf26023fccd1d087f6d90ec6048ff33ad0445abf7f605a \
+ --hash=sha256:7760c1c2e1a7084153a0f68fab76e754083b126a47d0117c9ed15e69e2103492 \
+ --hash=sha256:8c4a6ff8a30e9e3d38ac0539e9a9e02540ab3f827a3394f8852432f6b0ea152e \
+ --hash=sha256:9024beb59aca9d31d36fcdc1604dd9bbeed0a55bface9f1908df19178e2f116e \
+ --hash=sha256:90cb0a7bb35959f37e23303b7eed0a32280510030daba3f7fdfbb65defde6a97 \
+ --hash=sha256:91098f02ca81579c85f66df8a588c78f331ca19089763d733e34ad359f474174 \
+ --hash=sha256:926c3ea71a6043921050eaa639137e13dbe7b4ab25800932a8498364fc1abec9 \
+ --hash=sha256:982518cd64c54fcada9d7e5cf28eabd3ee76bd03ab18e08a48cad7e8b6f31b18 \
+ --hash=sha256:9b4cf6318915dccfe218e69bbec417fdd7c7185aa7aab139a2c0beb7468c89f0 \
+ --hash=sha256:ad0caded895a00261a5b4aa9af828baede54638754b51955a0ac75576b831b27 \
+ --hash=sha256:b85980d1e345fe769cfc57c57db2b59cff5464ee0c045d52c0df087e926fbe63 \
+ --hash=sha256:b8fa8b0a35a9982a3c60ec79905ba5bb090fc0b9addcfd3dc2dd04267e45f25e \
+ --hash=sha256:b9e38e0a83cd51e07f5a48ff9691cae95a79bea28fe4ded168a8e5c6c77e819d \
+ --hash=sha256:bd4c45986472694e5121084c6ebbd112aa919a25e783b87eb95953c9573906d6 \
+ --hash=sha256:be97d3a19c16a9be00edf79dca949c8fa7eff621763666a145f9f9535a5d7f42 \
+ --hash=sha256:c648025b6840fe62e57107e0a25f604db740e728bd67da4f6f060f03017d5097 \
+ --hash=sha256:d05a38884db2ba215218745f0781775806bde4f32e07b135348355fe8e4991d9 \
+ --hash=sha256:dd420e577921c8c2d31289536c386aaa30140b473835e97f83bc71ea9d2baf2d \
+ --hash=sha256:e357286c1b76403dd384d938f93c46b2b058ed4dfcdce64a770f0537ed3feb6f \
+ --hash=sha256:e6c00130ed423201c5bc5544c23359141660b07999ad82e34e7bb8f882bb78e0 \
+ --hash=sha256:e74d30ec9c7cb2f404af331d5b4099a9b322a8a6b25c4632755c8757345baac5 \
+ --hash=sha256:f3562c2f23c612f2e4a6964a61d942f891d29ee320edb62ff48ffb99f3de9ae8
+ # via pyjwt
+deprecated==1.2.18 \
+ --hash=sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d \
+ --hash=sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec
+ # via pygithub
docker==7.1.0 \
--hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \
--hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0
@@ -187,6 +301,30 @@ markupsafe==3.0.2 \
--hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \
--hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50
# via jinja2
+pycparser==2.22 \
+ --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \
+ --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc
+ # via cffi
+pygithub==2.6.1 \
+ --hash=sha256:6f2fa6d076ccae475f9fc392cc6cdbd54db985d4f69b8833a28397de75ed6ca3 \
+ --hash=sha256:b5c035392991cca63959e9453286b41b54d83bf2de2daa7d7ff7e4312cebf3bf
+ # via -r requirements.in
+pyjwt==2.10.1 \
+ --hash=sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953 \
+ --hash=sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb
+ # via pygithub
+pynacl==1.5.0 \
+ --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \
+ --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \
+ --hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \
+ --hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \
+ --hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \
+ --hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \
+ --hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \
+ --hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \
+ --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \
+ --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543
+ # via pygithub
pyyaml==6.0.2 \
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
--hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \
@@ -251,7 +389,9 @@ referencing==0.35.1 \
requests==2.32.3 \
--hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \
--hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6
- # via docker
+ # via
+ # docker
+ # pygithub
rpds-py==0.22.3 \
--hash=sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518 \
--hash=sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059 \
@@ -397,12 +537,100 @@ tomli==2.2.1 \
--hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \
--hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7
# via -r requirements.in
+typing-extensions==4.14.1 \
+ --hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \
+ --hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76
+ # via
+ # -r requirements.in
+ # pygithub
urllib3==2.3.0 \
--hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \
--hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d
# via
# docker
+ # pygithub
# requests
+wrapt==1.17.2 \
+ --hash=sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f \
+ --hash=sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c \
+ --hash=sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a \
+ --hash=sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b \
+ --hash=sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555 \
+ --hash=sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c \
+ --hash=sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b \
+ --hash=sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6 \
+ --hash=sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8 \
+ --hash=sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662 \
+ --hash=sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061 \
+ --hash=sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998 \
+ --hash=sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb \
+ --hash=sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62 \
+ --hash=sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984 \
+ --hash=sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392 \
+ --hash=sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2 \
+ --hash=sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306 \
+ --hash=sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7 \
+ --hash=sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3 \
+ --hash=sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9 \
+ --hash=sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6 \
+ --hash=sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192 \
+ --hash=sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317 \
+ --hash=sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f \
+ --hash=sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda \
+ --hash=sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563 \
+ --hash=sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a \
+ --hash=sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f \
+ --hash=sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d \
+ --hash=sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9 \
+ --hash=sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8 \
+ --hash=sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82 \
+ --hash=sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9 \
+ --hash=sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845 \
+ --hash=sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82 \
+ --hash=sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125 \
+ --hash=sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504 \
+ --hash=sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b \
+ --hash=sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7 \
+ --hash=sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc \
+ --hash=sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6 \
+ --hash=sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40 \
+ --hash=sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a \
+ --hash=sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3 \
+ --hash=sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a \
+ --hash=sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72 \
+ --hash=sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681 \
+ --hash=sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438 \
+ --hash=sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae \
+ --hash=sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2 \
+ --hash=sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb \
+ --hash=sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5 \
+ --hash=sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a \
+ --hash=sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3 \
+ --hash=sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8 \
+ --hash=sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2 \
+ --hash=sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22 \
+ --hash=sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72 \
+ --hash=sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061 \
+ --hash=sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f \
+ --hash=sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9 \
+ --hash=sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04 \
+ --hash=sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98 \
+ --hash=sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9 \
+ --hash=sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f \
+ --hash=sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b \
+ --hash=sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925 \
+ --hash=sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6 \
+ --hash=sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0 \
+ --hash=sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9 \
+ --hash=sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c \
+ --hash=sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991 \
+ --hash=sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6 \
+ --hash=sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000 \
+ --hash=sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb \
+ --hash=sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119 \
+ --hash=sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b \
+ --hash=sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58
+ # via deprecated
zstandard==0.23.0 \
--hash=sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473 \
--hash=sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916 \
diff --git a/requirements.win.txt b/requirements.win.txt
index a9132ab..899a4c5 100644
--- a/requirements.win.txt
+++ b/requirements.win.txt
@@ -10,6 +10,77 @@ certifi==2025.7.14 \
--hash=sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2 \
--hash=sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995
# via requests
+cffi==1.17.1 \
+ --hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \
+ --hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \
+ --hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \
+ --hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \
+ --hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \
+ --hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \
+ --hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \
+ --hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \
+ --hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \
+ --hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \
+ --hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \
+ --hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \
+ --hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \
+ --hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \
+ --hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \
+ --hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \
+ --hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \
+ --hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \
+ --hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \
+ --hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \
+ --hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \
+ --hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \
+ --hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \
+ --hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \
+ --hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \
+ --hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \
+ --hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \
+ --hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \
+ --hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \
+ --hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \
+ --hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \
+ --hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \
+ --hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \
+ --hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \
+ --hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \
+ --hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \
+ --hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \
+ --hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \
+ --hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \
+ --hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \
+ --hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \
+ --hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \
+ --hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \
+ --hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \
+ --hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \
+ --hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \
+ --hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \
+ --hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \
+ --hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \
+ --hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \
+ --hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \
+ --hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \
+ --hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \
+ --hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \
+ --hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \
+ --hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \
+ --hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \
+ --hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \
+ --hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \
+ --hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \
+ --hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \
+ --hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \
+ --hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \
+ --hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \
+ --hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \
+ --hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \
+ --hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b
+ # via
+ # cryptography
+ # pynacl
charset-normalizer==3.4.2 \
--hash=sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4 \
--hash=sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45 \
@@ -104,6 +175,49 @@ charset-normalizer==3.4.2 \
--hash=sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a \
--hash=sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f
# via requests
+cryptography==45.0.5 \
+ --hash=sha256:0027d566d65a38497bc37e0dd7c2f8ceda73597d2ac9ba93810204f56f52ebc7 \
+ --hash=sha256:101ee65078f6dd3e5a028d4f19c07ffa4dd22cce6a20eaa160f8b5219911e7d8 \
+ --hash=sha256:12e55281d993a793b0e883066f590c1ae1e802e3acb67f8b442e721e475e6463 \
+ --hash=sha256:14d96584701a887763384f3c47f0ca7c1cce322aa1c31172680eb596b890ec30 \
+ --hash=sha256:1e1da5accc0c750056c556a93c3e9cb828970206c68867712ca5805e46dc806f \
+ --hash=sha256:206210d03c1193f4e1ff681d22885181d47efa1ab3018766a7b32a7b3d6e6afd \
+ --hash=sha256:2089cc8f70a6e454601525e5bf2779e665d7865af002a5dec8d14e561002e135 \
+ --hash=sha256:3a264aae5f7fbb089dbc01e0242d3b67dffe3e6292e1f5182122bdf58e65215d \
+ --hash=sha256:3af26738f2db354aafe492fb3869e955b12b2ef2e16908c8b9cb928128d42c57 \
+ --hash=sha256:3fcfbefc4a7f332dece7272a88e410f611e79458fab97b5efe14e54fe476f4fd \
+ --hash=sha256:460f8c39ba66af7db0545a8c6f2eabcbc5a5528fc1cf6c3fa9a1e44cec33385e \
+ --hash=sha256:57c816dfbd1659a367831baca4b775b2a5b43c003daf52e9d57e1d30bc2e1b0e \
+ --hash=sha256:5aa1e32983d4443e310f726ee4b071ab7569f58eedfdd65e9675484a4eb67bd1 \
+ --hash=sha256:6ff8728d8d890b3dda5765276d1bc6fb099252915a2cd3aff960c4c195745dd0 \
+ --hash=sha256:7259038202a47fdecee7e62e0fd0b0738b6daa335354396c6ddebdbe1206af2a \
+ --hash=sha256:72e76caa004ab63accdf26023fccd1d087f6d90ec6048ff33ad0445abf7f605a \
+ --hash=sha256:7760c1c2e1a7084153a0f68fab76e754083b126a47d0117c9ed15e69e2103492 \
+ --hash=sha256:8c4a6ff8a30e9e3d38ac0539e9a9e02540ab3f827a3394f8852432f6b0ea152e \
+ --hash=sha256:9024beb59aca9d31d36fcdc1604dd9bbeed0a55bface9f1908df19178e2f116e \
+ --hash=sha256:90cb0a7bb35959f37e23303b7eed0a32280510030daba3f7fdfbb65defde6a97 \
+ --hash=sha256:91098f02ca81579c85f66df8a588c78f331ca19089763d733e34ad359f474174 \
+ --hash=sha256:926c3ea71a6043921050eaa639137e13dbe7b4ab25800932a8498364fc1abec9 \
+ --hash=sha256:982518cd64c54fcada9d7e5cf28eabd3ee76bd03ab18e08a48cad7e8b6f31b18 \
+ --hash=sha256:9b4cf6318915dccfe218e69bbec417fdd7c7185aa7aab139a2c0beb7468c89f0 \
+ --hash=sha256:ad0caded895a00261a5b4aa9af828baede54638754b51955a0ac75576b831b27 \
+ --hash=sha256:b85980d1e345fe769cfc57c57db2b59cff5464ee0c045d52c0df087e926fbe63 \
+ --hash=sha256:b8fa8b0a35a9982a3c60ec79905ba5bb090fc0b9addcfd3dc2dd04267e45f25e \
+ --hash=sha256:b9e38e0a83cd51e07f5a48ff9691cae95a79bea28fe4ded168a8e5c6c77e819d \
+ --hash=sha256:bd4c45986472694e5121084c6ebbd112aa919a25e783b87eb95953c9573906d6 \
+ --hash=sha256:be97d3a19c16a9be00edf79dca949c8fa7eff621763666a145f9f9535a5d7f42 \
+ --hash=sha256:c648025b6840fe62e57107e0a25f604db740e728bd67da4f6f060f03017d5097 \
+ --hash=sha256:d05a38884db2ba215218745f0781775806bde4f32e07b135348355fe8e4991d9 \
+ --hash=sha256:dd420e577921c8c2d31289536c386aaa30140b473835e97f83bc71ea9d2baf2d \
+ --hash=sha256:e357286c1b76403dd384d938f93c46b2b058ed4dfcdce64a770f0537ed3feb6f \
+ --hash=sha256:e6c00130ed423201c5bc5544c23359141660b07999ad82e34e7bb8f882bb78e0 \
+ --hash=sha256:e74d30ec9c7cb2f404af331d5b4099a9b322a8a6b25c4632755c8757345baac5 \
+ --hash=sha256:f3562c2f23c612f2e4a6964a61d942f891d29ee320edb62ff48ffb99f3de9ae8
+ # via pyjwt
+deprecated==1.2.18 \
+ --hash=sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d \
+ --hash=sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec
+ # via pygithub
docker==7.1.0 \
--hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \
--hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0
@@ -187,27 +301,47 @@ markupsafe==3.0.2 \
--hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \
--hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50
# via jinja2
-pywin32==311 \
- --hash=sha256:0502d1facf1fed4839a9a51ccbcc63d952cf318f78ffc00a7e78528ac27d7a2b \
- --hash=sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151 \
- --hash=sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87 \
- --hash=sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503 \
- --hash=sha256:62ea666235135fee79bb154e695f3ff67370afefd71bd7fea7512fc70ef31e3d \
- --hash=sha256:6c6f2969607b5023b0d9ce2541f8d2cbb01c4f46bc87456017cf63b73f1e2d8c \
- --hash=sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d \
- --hash=sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31 \
- --hash=sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b \
- --hash=sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a \
- --hash=sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42 \
- --hash=sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2 \
- --hash=sha256:aba8f82d551a942cb20d4a83413ccbac30790b50efb89a75e4f586ac0bb8056b \
- --hash=sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee \
- --hash=sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067 \
- --hash=sha256:c8015b09fb9a5e188f83b7b04de91ddca4658cee2ae6f3bc483f0b21a77ef6cd \
- --hash=sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3 \
- --hash=sha256:e0c4cfb0621281fe40387df582097fd796e80430597cb9944f0ae70447bacd91 \
- --hash=sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852 \
- --hash=sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d
+pycparser==2.22 \
+ --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \
+ --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc
+ # via cffi
+pygithub==2.6.1 \
+ --hash=sha256:6f2fa6d076ccae475f9fc392cc6cdbd54db985d4f69b8833a28397de75ed6ca3 \
+ --hash=sha256:b5c035392991cca63959e9453286b41b54d83bf2de2daa7d7ff7e4312cebf3bf
+ # via -r requirements.in
+pyjwt==2.10.1 \
+ --hash=sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953 \
+ --hash=sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb
+ # via pygithub
+pynacl==1.5.0 \
+ --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \
+ --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \
+ --hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \
+ --hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \
+ --hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \
+ --hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \
+ --hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \
+ --hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \
+ --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \
+ --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543
+ # via pygithub
+pywin32==310 \
+ --hash=sha256:0867beb8addefa2e3979d4084352e4ac6e991ca45373390775f7084cc0209b9c \
+ --hash=sha256:126298077a9d7c95c53823934f000599f66ec9296b09167810eb24875f32689c \
+ --hash=sha256:19ec5fc9b1d51c4350be7bb00760ffce46e6c95eaf2f0b2f1150657b1a43c582 \
+ --hash=sha256:1e765f9564e83011a63321bb9d27ec456a0ed90d3732c4b2e312b855365ed8bd \
+ --hash=sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966 \
+ --hash=sha256:30f0a9b3138fb5e07eb4973b7077e1883f558e40c578c6925acc7a94c34eaa36 \
+ --hash=sha256:33babed0cf0c92a6f94cc6cc13546ab24ee13e3e800e61ed87609ab91e4c8213 \
+ --hash=sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab \
+ --hash=sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e \
+ --hash=sha256:6dd97011efc8bf51d6793a82292419eba2c71cf8e7250cfac03bba284454abc1 \
+ --hash=sha256:851c8d927af0d879221e616ae1f66145253537bbdd321a77e8ef701b443a9a1a \
+ --hash=sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d \
+ --hash=sha256:96867217335559ac619f00ad70e513c0fcf84b8a3af9fc2bba3b59b97da70475 \
+ --hash=sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060 \
+ --hash=sha256:c3e78706e4229b915a0821941a84e7ef420bf2b77e08c9dae3c76fd03fd2ae3d \
+ --hash=sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33
# via docker
pyyaml==6.0.2 \
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
@@ -273,7 +407,9 @@ referencing==0.36.2 \
requests==2.32.4 \
--hash=sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c \
--hash=sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422
- # via docker
+ # via
+ # docker
+ # pygithub
rpds-py==0.26.0 \
--hash=sha256:0919f38f5542c0a87e7b4afcafab6fd2c15386632d249e9a087498571250abe3 \
--hash=sha256:093d63b4b0f52d98ebae33b8c50900d3d67e0666094b1be7a12fffd7f65de74b \
@@ -463,13 +599,97 @@ tomli==2.2.1 \
typing-extensions==4.14.1 \
--hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \
--hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76
- # via -r requirements.in
+ # via
+ # -r requirements.in
+ # pygithub
urllib3==2.5.0 \
--hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \
--hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc
# via
# docker
+ # pygithub
# requests
+wrapt==1.17.2 \
+ --hash=sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f \
+ --hash=sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c \
+ --hash=sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a \
+ --hash=sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b \
+ --hash=sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555 \
+ --hash=sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c \
+ --hash=sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b \
+ --hash=sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6 \
+ --hash=sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8 \
+ --hash=sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662 \
+ --hash=sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061 \
+ --hash=sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998 \
+ --hash=sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb \
+ --hash=sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62 \
+ --hash=sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984 \
+ --hash=sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392 \
+ --hash=sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2 \
+ --hash=sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306 \
+ --hash=sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7 \
+ --hash=sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3 \
+ --hash=sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9 \
+ --hash=sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6 \
+ --hash=sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192 \
+ --hash=sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317 \
+ --hash=sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f \
+ --hash=sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda \
+ --hash=sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563 \
+ --hash=sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a \
+ --hash=sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f \
+ --hash=sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d \
+ --hash=sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9 \
+ --hash=sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8 \
+ --hash=sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82 \
+ --hash=sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9 \
+ --hash=sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845 \
+ --hash=sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82 \
+ --hash=sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125 \
+ --hash=sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504 \
+ --hash=sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b \
+ --hash=sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7 \
+ --hash=sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc \
+ --hash=sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6 \
+ --hash=sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40 \
+ --hash=sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a \
+ --hash=sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3 \
+ --hash=sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a \
+ --hash=sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72 \
+ --hash=sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681 \
+ --hash=sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438 \
+ --hash=sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae \
+ --hash=sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2 \
+ --hash=sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb \
+ --hash=sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5 \
+ --hash=sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a \
+ --hash=sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3 \
+ --hash=sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8 \
+ --hash=sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2 \
+ --hash=sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22 \
+ --hash=sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72 \
+ --hash=sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061 \
+ --hash=sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f \
+ --hash=sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9 \
+ --hash=sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04 \
+ --hash=sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98 \
+ --hash=sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9 \
+ --hash=sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f \
+ --hash=sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b \
+ --hash=sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925 \
+ --hash=sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6 \
+ --hash=sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0 \
+ --hash=sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9 \
+ --hash=sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c \
+ --hash=sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991 \
+ --hash=sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6 \
+ --hash=sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000 \
+ --hash=sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb \
+ --hash=sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119 \
+ --hash=sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b \
+ --hash=sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58
+ # via deprecated
zstandard==0.23.0 \
--hash=sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473 \
--hash=sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916 \
From 680590fc5d3f697c0e68bc46800f075f911ca264 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Sat, 16 Aug 2025 08:13:02 -0500
Subject: [PATCH 53/72] Pin all of the actions (#763)
Closes https://github.com/astral-sh/python-build-standalone/issues/760
---
.github/workflows/check.yml | 4 +--
.github/workflows/linux.yml | 48 +++++++++++++++++------------------
.github/workflows/macos.yml | 22 ++++++++--------
.github/workflows/release.yml | 4 +--
.github/workflows/windows.yml | 20 +++++++--------
5 files changed, 49 insertions(+), 49 deletions(-)
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index c7874e7..0b06a31 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -19,10 +19,10 @@ jobs:
runs-on: "ubuntu-latest"
name: "check"
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
persist-credentials: false
- - uses: actions/setup-python@v5
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index edd5acb..911f05c 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -29,7 +29,7 @@ jobs:
sudo apt update
sudo apt install -y --no-install-recommends libssl-dev pkg-config
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
persist-credentials: false
@@ -37,7 +37,7 @@ jobs:
run: |
rustc --version > .rustc-version
- - uses: actions/cache@v4
+ - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: |
~/.cargo/registry
@@ -50,7 +50,7 @@ jobs:
cargo build --release
- name: Upload pythonbuild Executable
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ${{ matrix.crate_artifact_name }}
path: target/release/pythonbuild
@@ -67,20 +67,20 @@ jobs:
permissions:
packages: write
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
persist-credentials: false
- name: Install Python
- uses: actions/setup-python@v5
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.11"
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3
+ uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Login to GitHub Container Registry
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
+ uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -124,7 +124,7 @@ jobs:
MATRIX_ARCH: ${{ matrix.arch }}
- name: Upload Docker Image
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: image-${{ matrix.name }}-linux_${{ matrix.arch }}
path: build/image-*
@@ -139,13 +139,13 @@ jobs:
crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }}
any_builds: ${{ steps.set-matrix.outputs.any_builds }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Python
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0
- name: Get pull request labels
id: get-labels
@@ -211,31 +211,31 @@ jobs:
fail-fast: false
name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
persist-credentials: false
- name: Install Python
- uses: actions/setup-python@v5
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.11"
- name: Download pythonbuild
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: ${{ matrix.crate_artifact_name }}
path: build
- name: Download images
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: image-*
path: build
merge-multiple: true
- name: Cache downloads
- uses: actions/cache@v4
+ uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: build/downloads
key: ${{ matrix.target_triple }}-${{ hashFiles('pythonbuild/downloads.py')}}
@@ -271,14 +271,14 @@ jobs:
MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }}
- name: Generate attestations
- uses: actions/attest-build-provenance@v2
+ uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
if: ${{ github.ref == 'refs/heads/main' }}
with:
subject-path: dist/*
- name: Upload Distribution
if: ${{ ! matrix.dry-run }}
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }}
path: dist/*
@@ -319,31 +319,31 @@ jobs:
fail-fast: false
name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
persist-credentials: false
- name: Install Python
- uses: actions/setup-python@v5
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.11"
- name: Download pythonbuild
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: ${{ matrix.crate_artifact_name }}
path: build
- name: Download images
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: image-*
path: build
merge-multiple: true
- name: Cache downloads
- uses: actions/cache@v4
+ uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: build/downloads
key: ${{ matrix.target_triple }}-${{ hashFiles('pythonbuild/downloads.py')}}
@@ -379,14 +379,14 @@ jobs:
MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }}
- name: Generate attestations
- uses: actions/attest-build-provenance@v2
+ uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
if: ${{ github.ref == 'refs/heads/main' }}
with:
subject-path: dist/*
- name: Upload Distribution
if: ${{ ! matrix.dry-run }}
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }}
path: dist/*
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 02ce471..b746a96 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -24,7 +24,7 @@ jobs:
fail-fast: false
name: crate / ${{ matrix.arch }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
persist-credentials: false
@@ -32,7 +32,7 @@ jobs:
run: |
rustc --version > .rustc-version
- - uses: actions/cache@v4
+ - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: |
~/.cargo/registry
@@ -45,7 +45,7 @@ jobs:
cargo build --release
- name: Upload pythonbuild Executable
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ${{ matrix.crate_artifact_name }}
path: target/release/pythonbuild
@@ -58,13 +58,13 @@ jobs:
crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }}
any_builds: ${{ steps.set-matrix.outputs.any_builds }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Python
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0
- name: Get pull request labels
id: get-labels
@@ -123,18 +123,18 @@ jobs:
fail-fast: false
name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
persist-credentials: false
- name: Install Python
- uses: actions/setup-python@v5
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.11"
- name: Download pythonbuild
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: ${{ matrix.crate_artifact_name }}
path: build
@@ -158,21 +158,21 @@ jobs:
MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }}
- name: Generate attestations
- uses: actions/attest-build-provenance@v2
+ uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
if: ${{ github.ref == 'refs/heads/main' }}
with:
subject-path: dist/*
- name: Upload Distributions
if: ${{ ! matrix.dry-run }}
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: cpython-${{ matrix.python }}-${{ matrix.target_triple }}-${{ matrix.build_options }}
path: dist/*
- name: Checkout macOS SDKs for validation
if: ${{ ! matrix.dry-run }}
- uses: actions/checkout@v4
+ uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
repository: phracker/MacOSX-SDKs
ref: master
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 9c256ee..0a77d11 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -35,7 +35,7 @@ jobs:
attestations: write
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
submodules: recursive
persist-credentials: true # needed for git operations below
@@ -88,7 +88,7 @@ jobs:
GITHUB_EVENT_INPUTS_SHA: ${{ github.event.inputs.sha }}
GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }}
- name: Generate attestations
- uses: actions/attest-build-provenance@v2
+ uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
if: ${{ github.event.inputs.dry-run == 'false' }}
with:
subject-path: |
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 847a82e..94bdc04 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -24,7 +24,7 @@ jobs:
fail-fast: false
name: crate / ${{ matrix.arch }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
persist-credentials: false
@@ -32,7 +32,7 @@ jobs:
run: |
rustc --version > .rustc-version
- - uses: actions/cache@v4
+ - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: |
C:/Rust/.cargo/registry
@@ -45,7 +45,7 @@ jobs:
cargo build --release
- name: Upload executable
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ${{ matrix.crate_artifact_name }}
path: target/release/pythonbuild.exe
@@ -58,13 +58,13 @@ jobs:
crate-build-matrix: ${{ steps.set-matrix.outputs.crate-build-matrix }}
any_builds: ${{ steps.set-matrix.outputs.any_builds }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Python
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0
- name: Get pull request labels
id: get-labels
@@ -124,7 +124,7 @@ jobs:
fail-fast: false
name: ${{ matrix.target_triple }} / ${{ matrix.python }} / ${{ matrix.build_options }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
fetch-depth: 0
persist-credentials: false
@@ -135,12 +135,12 @@ jobs:
packages: autoconf automake libtool
- name: Install Python
- uses: actions/setup-python@v5
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"
- name: Download pythonbuild Executable
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: ${{ matrix.crate_artifact_name }}
@@ -162,13 +162,13 @@ jobs:
MATRIX_BUILD_OPTIONS: ${{ matrix.build_options }}
- name: Generate attestations
- uses: actions/attest-build-provenance@v2
+ uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
if: ${{ github.ref == 'refs/heads/main' }}
with:
subject-path: dist/*
- name: Upload Distributions
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: cpython-${{ matrix.python }}-${{ matrix.vcvars }}-${{ matrix.build_options }}
path: dist/*
From e2508053e9455b0845f56f0f0a04b2b1864059a5 Mon Sep 17 00:00:00 2001
From: William Woodruff
Date: Sun, 17 Aug 2025 14:30:50 -0400
Subject: [PATCH 54/72] chore(ci): drop ref-pin exceptions in zizmor (#765)
---
.github/zizmor.yml | 2 --
1 file changed, 2 deletions(-)
diff --git a/.github/zizmor.yml b/.github/zizmor.yml
index c3db968..e7920e8 100644
--- a/.github/zizmor.yml
+++ b/.github/zizmor.yml
@@ -2,6 +2,4 @@ rules:
unpinned-uses:
config:
policies:
- actions/*: ref-pin
- astral-sh/*: ref-pin
"*": hash-pin
From 38904395690730fb5c7ecaf414e8f48508014480 Mon Sep 17 00:00:00 2001
From: Dustin Rodrigues
Date: Mon, 18 Aug 2025 09:33:22 -0400
Subject: [PATCH 55/72] only define MODULE_NAME for sqlite on python <= 3.9
(#767)
Starting in Python 3.10, -DMODULE_NAME="sqlite3" is no longer needed
when building _sqlite3.
https://github.com/python/cpython/issues/87610 /
https://github.com/python/cpython/pull/24801
---
cpython-unix/extension-modules.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/cpython-unix/extension-modules.yml b/cpython-unix/extension-modules.yml
index 4f9acc0..214d90a 100644
--- a/cpython-unix/extension-modules.yml
+++ b/cpython-unix/extension-modules.yml
@@ -533,8 +533,6 @@ _sqlite3:
- include
includes:
- Modules/_sqlite
- defines:
- - "MODULE_NAME=\\\"sqlite3\\\""
defines-conditional:
# Require dynamic binaries to load extensions. Cannot load on iOS.
# 3.11+ uses opt in. <3.11 uses opt out.
@@ -548,6 +546,8 @@ _sqlite3:
- define: SQLITE_OMIT_LOAD_EXTENSION=1
targets:
- .*-ios
+ - define: "MODULE_NAME=\\\"sqlite3\\\""
+ maximum-python-version: "3.9"
links:
- sqlite3
From 947a810a8402399af117054e236dfe2ecf7caf26 Mon Sep 17 00:00:00 2001
From: Chowder <16789070+chowder@users.noreply.github.com>
Date: Mon, 18 Aug 2025 14:35:59 +0100
Subject: [PATCH 56/72] Reproducible artifact hashes for base builder images
(#766)
I was looking at the build pipeline for the distributions, and was
surprised to find the builder image artifacts having different SHA256
hashes across runs.
e.g. compare the output of the "Upload Docker Image" step of two jobs:
https://github.com/chowder/python-build-standalone/actions/runs/17012490960/job/48230404008
https://github.com/chowder/python-build-standalone/actions/runs/17012490960/job/48230532790
For the same image:
```
SHA256 digest of uploaded artifact zip is d47e11cc1c0e648bed6ec64a3613fa166c317981d252085c241c05745604973b
Finalizing artifact upload
Artifact image-build-linux_x86_64.zip successfully finalized. Artifact ID 3780654566
Artifact image-build-linux_x86_64 has been successfully uploaded! Final size is 80890477 bytes. Artifact ID is 3780654566
```
```
SHA256 digest of uploaded artifact zip is 3341d64b1d7efb680db3e4d62ae3dab9bf24e22e384f585aaf3a5b551aee5e7b
Finalizing artifact upload
Artifact image-build-linux_x86_64.zip successfully finalized. Artifact ID 3780667100
Artifact image-build-linux_x86_64 has been successfully uploaded! Final size is 80890477 bytes. Artifact ID is 3780667100
```
Turns out this is because the `upload-artifact` step applies a layer of
compression to the specified files, but doesn't reset/zero out the
mtime, thus making these artifacts non-reproducible.
Given that the docker images are already compressed [in a prior
step](https://github.com/astral-sh/python-build-standalone/blob/main/.github/workflows/linux.yml#L117-L120):
```yaml
- name: Compress Image
run: |
echo ${STEPS_BUILD_IMAGE_OUTPUTS_IMAGEID} > build/image-${MATRIX_NAME}.linux_${MATRIX_ARCH}
zstd -v -T0 -6 --rm build/image-*.tar
```
We can skip the compression in the `upload-artifact` step, and get
reproducible artifacts each time.
#### Test Evidence
See these two runs that include the proposed changes:
https://github.com/chowder/python-build-standalone/actions/runs/17012517183/job/48230459046
https://github.com/chowder/python-build-standalone/actions/runs/17012517183/job/48230772691
Both generate the same digest:
```
Finished uploading artifact content to blob storage!
SHA256 digest of uploaded artifact zip is c73f01690d74c103f92bd8113ff158e8b8d2d4de19dca96d36b3d6fbc688fe16
Finalizing artifact upload
Artifact image-build-linux_x86_64.zip successfully finalized. Artifact ID 3780661038
Artifact image-build-linux_x86_64 has been successfully uploaded! Final size is 81208314 bytes. Artifact ID is 3780661038
```
```
SHA256 digest of uploaded artifact zip is c73f01690d74c103f92bd8113ff158e8b8d2d4de19dca96d36b3d6fbc688fe16
Finalizing artifact upload
Artifact image-build-linux_x86_64.zip successfully finalized. Artifact ID 3780693018
Artifact image-build-linux_x86_64 has been successfully uploaded! Final size is 81208314 bytes. Artifact ID is 3780693018
```
---
.github/workflows/linux.yml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 911f05c..68eef0e 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -97,6 +97,8 @@ jobs:
- name: Build Image
id: build-image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
+ env:
+ SOURCE_DATE_EPOCH: 0
with:
context: .
file: build/${{ matrix.name }}.Dockerfile
@@ -118,6 +120,7 @@ jobs:
run: |
echo ${STEPS_BUILD_IMAGE_OUTPUTS_IMAGEID} > build/image-${MATRIX_NAME}.linux_${MATRIX_ARCH}
zstd -v -T0 -6 --rm build/image-*.tar
+ touch -t 197001010000 build/image-*
env:
STEPS_BUILD_IMAGE_OUTPUTS_IMAGEID: ${{ steps.build-image.outputs.imageid }}
MATRIX_NAME: ${{ matrix.name }}
@@ -128,6 +131,7 @@ jobs:
with:
name: image-${{ matrix.name }}-linux_${{ matrix.arch }}
path: build/image-*
+ compression-level: '0'
generate-matrix:
name: Generate build matrix
From c744db99c53b6ed609455eb8aaf08eebc05f20a7 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Mon, 18 Aug 2025 08:42:40 -0500
Subject: [PATCH 57/72] Build zstd with multithreading enabled (#762)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
I verified this on macOS
```
❯ python -c "from compression import zstd; print(zstd.CompressionParameter.nb_workers.bounds())"
(0, 256)
```
See #761
I'm not sure if this is all of the performance difference, but using
threads should make a significant difference.
https://github.com/astral-sh/python-build-standalone/issues/761#issuecomment-3193682600
notes that threads are not used by default, so I think there's more
going on — but we should enable this at build time regardless. See also
#768.
---
cpython-unix/build-zstd.sh | 4 ++--
src/verify_distribution.py | 9 +++++++++
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/cpython-unix/build-zstd.sh b/cpython-unix/build-zstd.sh
index e81ef78..e9b830c 100755
--- a/cpython-unix/build-zstd.sh
+++ b/cpython-unix/build-zstd.sh
@@ -57,7 +57,7 @@ index 5e6e8bc..6ca72a1 100644
EOF
fi
-CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" make -j ${NUM_CPUS} libzstd.a
+CFLAGS="${EXTRA_TARGET_CFLAGS} -DZSTD_MULTITHREAD -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" make -j ${NUM_CPUS} libzstd.a
make -j ${NUM_CPUS} install-static DESTDIR=${ROOT}/out
make -j ${NUM_CPUS} install-includes DESTDIR=${ROOT}/out
-make -j ${NUM_CPUS} install-pc DESTDIR=${ROOT}/out
+MT=1 make -j ${NUM_CPUS} install-pc DESTDIR=${ROOT}/out
diff --git a/src/verify_distribution.py b/src/verify_distribution.py
index d6e428d..62e787b 100644
--- a/src/verify_distribution.py
+++ b/src/verify_distribution.py
@@ -172,6 +172,15 @@ def test_gil_disabled(self):
self.assertEqual(sysconfig.get_config_var("Py_GIL_DISABLED"), wanted)
+ @unittest.skipIf(
+ sys.version_info[:2] < (3, 14),
+ "zstd is only available in 3.14+",
+ )
+ def test_zstd_multithreaded(self):
+ from compression import zstd
+
+ assert zstd.CompressionParameter.nb_workers.bounds() == (0, 256)
+
@unittest.skipIf("TCL_LIBRARY" not in os.environ, "TCL_LIBRARY not set")
@unittest.skipIf("DISPLAY" not in os.environ, "DISPLAY not set")
def test_tkinter(self):
From 5884554a15d1cd0c7a13e78580c1a2ab514dd695 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Mon, 18 Aug 2025 08:44:14 -0500
Subject: [PATCH 58/72] Build zstd with optimizations enabled (#768)
Also, enable verbose output in the build system because it is otherwise
too quiet to be helpful.
See
https://github.com/astral-sh/python-build-standalone/issues/761#issuecomment-3194589916
---
cpython-unix/build-zstd.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cpython-unix/build-zstd.sh b/cpython-unix/build-zstd.sh
index e9b830c..5a889da 100755
--- a/cpython-unix/build-zstd.sh
+++ b/cpython-unix/build-zstd.sh
@@ -57,7 +57,7 @@ index 5e6e8bc..6ca72a1 100644
EOF
fi
-CFLAGS="${EXTRA_TARGET_CFLAGS} -DZSTD_MULTITHREAD -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" make -j ${NUM_CPUS} libzstd.a
+CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC -DZSTD_MULTITHREAD -O3" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" make -j ${NUM_CPUS} VERBOSE=1 libzstd.a
make -j ${NUM_CPUS} install-static DESTDIR=${ROOT}/out
make -j ${NUM_CPUS} install-includes DESTDIR=${ROOT}/out
MT=1 make -j ${NUM_CPUS} install-pc DESTDIR=${ROOT}/out
From 01aa80641edfca8efa1a8f7c3b9bb0405bde1512 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Mon, 18 Aug 2025 08:54:08 -0500
Subject: [PATCH 59/72] Exclude pygithub on arm64 Windows (#769)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Addressing the environment bootstrap regression from #706 — we can't
build `cryptography` and `pynacl` from source and we don't need download
statistics in CI.
---
build-windows.py | 4 +-
pythonbuild/utils.py | 3 +-
requirements.in | 4 +-
requirements.win-arm64.txt | 571 +++++++++++++++++++++++++++++++++++++
4 files changed, 579 insertions(+), 3 deletions(-)
create mode 100644 requirements.win-arm64.txt
diff --git a/build-windows.py b/build-windows.py
index df836b6..4a8c897 100644
--- a/build-windows.py
+++ b/build-windows.py
@@ -5,6 +5,7 @@
import os
import pathlib
+import platform
import subprocess
import sys
import venv
@@ -15,7 +16,8 @@
VENV = BUILD / "venv"
PIP = VENV / "Scripts" / "pip.exe"
PYTHON = VENV / "Scripts" / "python.exe"
-REQUIREMENTS = ROOT / "requirements.win.txt"
+ARCH = "-arm64" if platform.machine() == "ARM64" else ""
+REQUIREMENTS = ROOT / f"requirements.win{ARCH}.txt"
WINDOWS_DIR = ROOT / "cpython-windows"
diff --git a/pythonbuild/utils.py b/pythonbuild/utils.py
index f784dc1..9e581c5 100644
--- a/pythonbuild/utils.py
+++ b/pythonbuild/utils.py
@@ -23,7 +23,6 @@
import urllib.request
import zipfile
-import github
import yaml
import zstandard
@@ -654,6 +653,8 @@ def validate_python_json(info, extension_modules):
def release_download_statistics(mode="by_asset"):
+ import github
+
by_tag = collections.Counter()
by_build = collections.Counter()
by_build_install_only = collections.Counter()
diff --git a/requirements.in b/requirements.in
index 552e62d..e9159b6 100644
--- a/requirements.in
+++ b/requirements.in
@@ -1,7 +1,9 @@
docker
jinja2
jsonschema
-PyGithub
+# This does not built on the aarch64-windows runners yet, and is only needed for
+# development so we'll just skip it for now.
+PyGithub; sys_platform != "win32" or platform_machine != "aarch64"
PyYAML
# Undeclared dependency in docker 5.0 package.
six
diff --git a/requirements.win-arm64.txt b/requirements.win-arm64.txt
new file mode 100644
index 0000000..11b0502
--- /dev/null
+++ b/requirements.win-arm64.txt
@@ -0,0 +1,571 @@
+# This file was autogenerated by uv via the following command:
+# uv pip compile --python-platform aarch64-pc-windows-msvc --generate-hashes requirements.in -o requirements.win-arm64.txt
+attrs==25.3.0 \
+ --hash=sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3 \
+ --hash=sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b
+ # via
+ # jsonschema
+ # referencing
+certifi==2025.8.3 \
+ --hash=sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407 \
+ --hash=sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5
+ # via requests
+charset-normalizer==3.4.3 \
+ --hash=sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91 \
+ --hash=sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0 \
+ --hash=sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154 \
+ --hash=sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601 \
+ --hash=sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884 \
+ --hash=sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07 \
+ --hash=sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c \
+ --hash=sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64 \
+ --hash=sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe \
+ --hash=sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f \
+ --hash=sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432 \
+ --hash=sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc \
+ --hash=sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa \
+ --hash=sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9 \
+ --hash=sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae \
+ --hash=sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19 \
+ --hash=sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d \
+ --hash=sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e \
+ --hash=sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4 \
+ --hash=sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7 \
+ --hash=sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312 \
+ --hash=sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92 \
+ --hash=sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31 \
+ --hash=sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c \
+ --hash=sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f \
+ --hash=sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99 \
+ --hash=sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b \
+ --hash=sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15 \
+ --hash=sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392 \
+ --hash=sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f \
+ --hash=sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8 \
+ --hash=sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491 \
+ --hash=sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0 \
+ --hash=sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc \
+ --hash=sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0 \
+ --hash=sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f \
+ --hash=sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a \
+ --hash=sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40 \
+ --hash=sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927 \
+ --hash=sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849 \
+ --hash=sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce \
+ --hash=sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14 \
+ --hash=sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05 \
+ --hash=sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c \
+ --hash=sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c \
+ --hash=sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a \
+ --hash=sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc \
+ --hash=sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34 \
+ --hash=sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9 \
+ --hash=sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096 \
+ --hash=sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14 \
+ --hash=sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30 \
+ --hash=sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b \
+ --hash=sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b \
+ --hash=sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942 \
+ --hash=sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db \
+ --hash=sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5 \
+ --hash=sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b \
+ --hash=sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce \
+ --hash=sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669 \
+ --hash=sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0 \
+ --hash=sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018 \
+ --hash=sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93 \
+ --hash=sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe \
+ --hash=sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049 \
+ --hash=sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a \
+ --hash=sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef \
+ --hash=sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2 \
+ --hash=sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca \
+ --hash=sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16 \
+ --hash=sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f \
+ --hash=sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb \
+ --hash=sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1 \
+ --hash=sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557 \
+ --hash=sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37 \
+ --hash=sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7 \
+ --hash=sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72 \
+ --hash=sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c \
+ --hash=sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9
+ # via requests
+docker==7.1.0 \
+ --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \
+ --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0
+ # via -r requirements.in
+idna==3.10 \
+ --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \
+ --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3
+ # via requests
+jinja2==3.1.6 \
+ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \
+ --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67
+ # via -r requirements.in
+jsonschema==4.25.0 \
+ --hash=sha256:24c2e8da302de79c8b9382fee3e76b355e44d2a4364bb207159ce10b517bd716 \
+ --hash=sha256:e63acf5c11762c0e6672ffb61482bdf57f0876684d8d249c0fe2d730d48bc55f
+ # via -r requirements.in
+jsonschema-specifications==2025.4.1 \
+ --hash=sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af \
+ --hash=sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608
+ # via jsonschema
+markupsafe==3.0.2 \
+ --hash=sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4 \
+ --hash=sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30 \
+ --hash=sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0 \
+ --hash=sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9 \
+ --hash=sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 \
+ --hash=sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13 \
+ --hash=sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028 \
+ --hash=sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca \
+ --hash=sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557 \
+ --hash=sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832 \
+ --hash=sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0 \
+ --hash=sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b \
+ --hash=sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579 \
+ --hash=sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a \
+ --hash=sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c \
+ --hash=sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff \
+ --hash=sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c \
+ --hash=sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22 \
+ --hash=sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094 \
+ --hash=sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb \
+ --hash=sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e \
+ --hash=sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5 \
+ --hash=sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a \
+ --hash=sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d \
+ --hash=sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a \
+ --hash=sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b \
+ --hash=sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8 \
+ --hash=sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225 \
+ --hash=sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c \
+ --hash=sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144 \
+ --hash=sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f \
+ --hash=sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87 \
+ --hash=sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d \
+ --hash=sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93 \
+ --hash=sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf \
+ --hash=sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158 \
+ --hash=sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84 \
+ --hash=sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb \
+ --hash=sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48 \
+ --hash=sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171 \
+ --hash=sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c \
+ --hash=sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6 \
+ --hash=sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd \
+ --hash=sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d \
+ --hash=sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1 \
+ --hash=sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d \
+ --hash=sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca \
+ --hash=sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a \
+ --hash=sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29 \
+ --hash=sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe \
+ --hash=sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798 \
+ --hash=sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c \
+ --hash=sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8 \
+ --hash=sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f \
+ --hash=sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f \
+ --hash=sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a \
+ --hash=sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178 \
+ --hash=sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0 \
+ --hash=sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79 \
+ --hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \
+ --hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50
+ # via jinja2
+pywin32==311 \
+ --hash=sha256:0502d1facf1fed4839a9a51ccbcc63d952cf318f78ffc00a7e78528ac27d7a2b \
+ --hash=sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151 \
+ --hash=sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87 \
+ --hash=sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503 \
+ --hash=sha256:62ea666235135fee79bb154e695f3ff67370afefd71bd7fea7512fc70ef31e3d \
+ --hash=sha256:6c6f2969607b5023b0d9ce2541f8d2cbb01c4f46bc87456017cf63b73f1e2d8c \
+ --hash=sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d \
+ --hash=sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31 \
+ --hash=sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b \
+ --hash=sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a \
+ --hash=sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42 \
+ --hash=sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2 \
+ --hash=sha256:aba8f82d551a942cb20d4a83413ccbac30790b50efb89a75e4f586ac0bb8056b \
+ --hash=sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee \
+ --hash=sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067 \
+ --hash=sha256:c8015b09fb9a5e188f83b7b04de91ddca4658cee2ae6f3bc483f0b21a77ef6cd \
+ --hash=sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3 \
+ --hash=sha256:e0c4cfb0621281fe40387df582097fd796e80430597cb9944f0ae70447bacd91 \
+ --hash=sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852 \
+ --hash=sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d
+ # via docker
+pyyaml==6.0.2 \
+ --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
+ --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \
+ --hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \
+ --hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \
+ --hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \
+ --hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \
+ --hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \
+ --hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \
+ --hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \
+ --hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \
+ --hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \
+ --hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \
+ --hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \
+ --hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \
+ --hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \
+ --hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \
+ --hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \
+ --hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \
+ --hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \
+ --hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \
+ --hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \
+ --hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \
+ --hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \
+ --hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \
+ --hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \
+ --hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \
+ --hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \
+ --hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \
+ --hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \
+ --hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \
+ --hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \
+ --hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \
+ --hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \
+ --hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \
+ --hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \
+ --hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \
+ --hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \
+ --hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \
+ --hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \
+ --hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \
+ --hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \
+ --hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \
+ --hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \
+ --hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \
+ --hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \
+ --hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \
+ --hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \
+ --hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \
+ --hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \
+ --hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \
+ --hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \
+ --hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \
+ --hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4
+ # via -r requirements.in
+referencing==0.36.2 \
+ --hash=sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa \
+ --hash=sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0
+ # via
+ # jsonschema
+ # jsonschema-specifications
+requests==2.32.4 \
+ --hash=sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c \
+ --hash=sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422
+ # via docker
+rpds-py==0.27.0 \
+ --hash=sha256:010c4843a3b92b54373e3d2291a7447d6c3fc29f591772cc2ea0e9f5c1da434b \
+ --hash=sha256:05284439ebe7d9f5f5a668d4d8a0a1d851d16f7d47c78e1fab968c8ad30cab04 \
+ --hash=sha256:0665be515767dc727ffa5f74bd2ef60b0ff85dad6bb8f50d91eaa6b5fb226f51 \
+ --hash=sha256:069e0384a54f427bd65d7fda83b68a90606a3835901aaff42185fcd94f5a9295 \
+ --hash=sha256:08680820d23df1df0a0260f714d12966bc6c42d02e8055a91d61e03f0c47dda0 \
+ --hash=sha256:0954e3a92e1d62e83a54ea7b3fdc9efa5d61acef8488a8a3d31fdafbfb00460d \
+ --hash=sha256:09965b314091829b378b60607022048953e25f0b396c2b70e7c4c81bcecf932e \
+ --hash=sha256:0c431bfb91478d7cbe368d0a699978050d3b112d7f1d440a41e90faa325557fd \
+ --hash=sha256:0f401c369186a5743694dd9fc08cba66cf70908757552e1f714bfc5219c655b5 \
+ --hash=sha256:0f4f69d7a4300fbf91efb1fb4916421bd57804c01ab938ab50ac9c4aa2212f03 \
+ --hash=sha256:11e8e28c0ba0373d052818b600474cfee2fafa6c9f36c8587d217b13ee28ca7d \
+ --hash=sha256:130c1ffa5039a333f5926b09e346ab335f0d4ec393b030a18549a7c7e7c2cea4 \
+ --hash=sha256:1321bce595ad70e80f97f998db37356b2e22cf98094eba6fe91782e626da2f71 \
+ --hash=sha256:13bbc4846ae4c993f07c93feb21a24d8ec637573d567a924b1001e81c8ae80f9 \
+ --hash=sha256:14f028eb47f59e9169bfdf9f7ceafd29dd64902141840633683d0bad5b04ff34 \
+ --hash=sha256:15ea4d2e182345dd1b4286593601d766411b43f868924afe297570658c31a62b \
+ --hash=sha256:181bc29e59e5e5e6e9d63b143ff4d5191224d355e246b5a48c88ce6b35c4e466 \
+ --hash=sha256:183f5e221ba3e283cd36fdfbe311d95cd87699a083330b4f792543987167eff1 \
+ --hash=sha256:184f0d7b342967f6cda94a07d0e1fae177d11d0b8f17d73e06e36ac02889f303 \
+ --hash=sha256:190d7285cd3bb6d31d37a0534d7359c1ee191eb194c511c301f32a4afa5a1dd4 \
+ --hash=sha256:19c990fdf5acecbf0623e906ae2e09ce1c58947197f9bced6bbd7482662231c4 \
+ --hash=sha256:1d66f45b9399036e890fb9c04e9f70c33857fd8f58ac8db9f3278cfa835440c3 \
+ --hash=sha256:203f581accef67300a942e49a37d74c12ceeef4514874c7cede21b012613ca2c \
+ --hash=sha256:20e222a44ae9f507d0f2678ee3dd0c45ec1e930f6875d99b8459631c24058aec \
+ --hash=sha256:2406d034635d1497c596c40c85f86ecf2bf9611c1df73d14078af8444fe48031 \
+ --hash=sha256:249ab91ceaa6b41abc5f19513cb95b45c6f956f6b89f1fe3d99c81255a849f9e \
+ --hash=sha256:25a4aebf8ca02bbb90a9b3e7a463bbf3bee02ab1c446840ca07b1695a68ce424 \
+ --hash=sha256:27bac29bbbf39601b2aab474daf99dbc8e7176ca3389237a23944b17f8913d97 \
+ --hash=sha256:299a245537e697f28a7511d01038c310ac74e8ea213c0019e1fc65f52c0dcb23 \
+ --hash=sha256:2cff9bdd6c7b906cc562a505c04a57d92e82d37200027e8d362518df427f96cd \
+ --hash=sha256:2e307cb5f66c59ede95c00e93cd84190a5b7f3533d7953690b2036780622ba81 \
+ --hash=sha256:2e39169ac6aae06dd79c07c8a69d9da867cef6a6d7883a0186b46bb46ccfb0c3 \
+ --hash=sha256:2fe6e18e5c8581f0361b35ae575043c7029d0a92cb3429e6e596c2cdde251432 \
+ --hash=sha256:3001013dae10f806380ba739d40dee11db1ecb91684febb8406a87c2ded23dae \
+ --hash=sha256:32196b5a99821476537b3f7732432d64d93a58d680a52c5e12a190ee0135d8b5 \
+ --hash=sha256:33ba649a6e55ae3808e4c39e01580dc9a9b0d5b02e77b66bb86ef117922b1264 \
+ --hash=sha256:341d8acb6724c0c17bdf714319c393bb27f6d23d39bc74f94221b3e59fc31828 \
+ --hash=sha256:343cf24de9ed6c728abefc5d5c851d5de06497caa7ac37e5e65dd572921ed1b5 \
+ --hash=sha256:36184b44bf60a480863e51021c26aca3dfe8dd2f5eeabb33622b132b9d8b8b54 \
+ --hash=sha256:3841f66c1ffdc6cebce8aed64e36db71466f1dc23c0d9a5592e2a782a3042c79 \
+ --hash=sha256:4045e2fc4b37ec4b48e8907a5819bdd3380708c139d7cc358f03a3653abedb89 \
+ --hash=sha256:419dd9c98bcc9fb0242be89e0c6e922df333b975d4268faa90d58499fd9c9ebe \
+ --hash=sha256:42894616da0fc0dcb2ec08a77896c3f56e9cb2f4b66acd76fc8992c3557ceb1c \
+ --hash=sha256:42ccc57ff99166a55a59d8c7d14f1a357b7749f9ed3584df74053fd098243451 \
+ --hash=sha256:4300e15e7d03660f04be84a125d1bdd0e6b2f674bc0723bc0fd0122f1a4585dc \
+ --hash=sha256:443d239d02d9ae55b74015234f2cd8eb09e59fbba30bf60baeb3123ad4c6d5ff \
+ --hash=sha256:44524b96481a4c9b8e6c46d6afe43fa1fb485c261e359fbe32b63ff60e3884d8 \
+ --hash=sha256:45d04a73c54b6a5fd2bab91a4b5bc8b426949586e61340e212a8484919183859 \
+ --hash=sha256:46f48482c1a4748ab2773f75fffbdd1951eb59794e32788834b945da857c47a8 \
+ --hash=sha256:4790c9d5dd565ddb3e9f656092f57268951398cef52e364c405ed3112dc7c7c1 \
+ --hash=sha256:4bc262ace5a1a7dc3e2eac2fa97b8257ae795389f688b5adf22c5db1e2431c43 \
+ --hash=sha256:4c3f8a0d4802df34fcdbeb3dfe3a4d8c9a530baea8fafdf80816fcaac5379d83 \
+ --hash=sha256:5355527adaa713ab693cbce7c1e0ec71682f599f61b128cf19d07e5c13c9b1f1 \
+ --hash=sha256:555ed147cbe8c8f76e72a4c6cd3b7b761cbf9987891b9448808148204aed74a5 \
+ --hash=sha256:55d42a0ef2bdf6bc81e1cc2d49d12460f63c6ae1423c4f4851b828e454ccf6f1 \
+ --hash=sha256:59195dc244fc183209cf8a93406889cadde47dfd2f0a6b137783aa9c56d67c85 \
+ --hash=sha256:59714ab0a5af25d723d8e9816638faf7f4254234decb7d212715c1aa71eee7be \
+ --hash=sha256:5b3a5c8089eed498a3af23ce87a80805ff98f6ef8f7bdb70bd1b7dae5105f6ac \
+ --hash=sha256:5d6790ff400254137b81b8053b34417e2c46921e302d655181d55ea46df58cf7 \
+ --hash=sha256:5df559e9e7644d9042f626f2c3997b555f347d7a855a15f170b253f6c5bfe358 \
+ --hash=sha256:5fa01b3d5e3b7d97efab65bd3d88f164e289ec323a8c033c5c38e53ee25c007e \
+ --hash=sha256:61490d57e82e23b45c66f96184237994bfafa914433b8cd1a9bb57fecfced59d \
+ --hash=sha256:6168af0be75bba990a39f9431cdfae5f0ad501f4af32ae62e8856307200517b8 \
+ --hash=sha256:64a0fe3f334a40b989812de70160de6b0ec7e3c9e4a04c0bbc48d97c5d3600ae \
+ --hash=sha256:64f689ab822f9b5eb6dfc69893b4b9366db1d2420f7db1f6a2adf2a9ca15ad64 \
+ --hash=sha256:699c346abc73993962cac7bb4f02f58e438840fa5458a048d3a178a7a670ba86 \
+ --hash=sha256:6b96b0b784fe5fd03beffff2b1533dc0d85e92bab8d1b2c24ef3a5dc8fac5669 \
+ --hash=sha256:6bde37765564cd22a676dd8101b657839a1854cfaa9c382c5abf6ff7accfd4ae \
+ --hash=sha256:6c135708e987f46053e0a1246a206f53717f9fadfba27174a9769ad4befba5c3 \
+ --hash=sha256:6c27a7054b5224710fcfb1a626ec3ff4f28bcb89b899148c72873b18210e446b \
+ --hash=sha256:6de6a7f622860af0146cb9ee148682ff4d0cea0b8fd3ad51ce4d40efb2f061d0 \
+ --hash=sha256:737005088449ddd3b3df5a95476ee1c2c5c669f5c30eed909548a92939c0e12d \
+ --hash=sha256:7451ede3560086abe1aa27dcdcf55cd15c96b56f543fb12e5826eee6f721f858 \
+ --hash=sha256:7873b65686a6471c0037139aa000d23fe94628e0daaa27b6e40607c90e3f5ec4 \
+ --hash=sha256:79af163a4b40bbd8cfd7ca86ec8b54b81121d3b213b4435ea27d6568bcba3e9d \
+ --hash=sha256:7aed8118ae20515974650d08eb724150dc2e20c2814bcc307089569995e88a14 \
+ --hash=sha256:7cf9bc4508efb18d8dff6934b602324eb9f8c6644749627ce001d6f38a490889 \
+ --hash=sha256:7e57906e38583a2cba67046a09c2637e23297618dc1f3caddbc493f2be97c93f \
+ --hash=sha256:7ec85994f96a58cf7ed288caa344b7fe31fd1d503bdf13d7331ead5f70ab60d5 \
+ --hash=sha256:81f81bbd7cdb4bdc418c09a73809abeda8f263a6bf8f9c7f93ed98b5597af39d \
+ --hash=sha256:86aca1616922b40d8ac1b3073a1ead4255a2f13405e5700c01f7c8d29a03972d \
+ --hash=sha256:88051c3b7d5325409f433c5a40328fcb0685fc04e5db49ff936e910901d10114 \
+ --hash=sha256:887ab1f12b0d227e9260558a4a2320024b20102207ada65c43e1ffc4546df72e \
+ --hash=sha256:8a06aa1197ec0281eb1d7daf6073e199eb832fe591ffa329b88bae28f25f5fe5 \
+ --hash=sha256:8a1dca5507fa1337f75dcd5070218b20bc68cf8844271c923c1b79dfcbc20391 \
+ --hash=sha256:8b23cf252f180cda89220b378d917180f29d313cd6a07b2431c0d3b776aae86f \
+ --hash=sha256:8d0e09cf4863c74106b5265c2c310f36146e2b445ff7b3018a56799f28f39f6f \
+ --hash=sha256:8de567dec6d451649a781633d36f5c7501711adee329d76c095be2178855b042 \
+ --hash=sha256:90fb790138c1a89a2e58c9282fe1089638401f2f3b8dddd758499041bc6e0774 \
+ --hash=sha256:92f3b3ec3e6008a1fe00b7c0946a170f161ac00645cde35e3c9a68c2475e8156 \
+ --hash=sha256:935afcdea4751b0ac918047a2df3f720212892347767aea28f5b3bf7be4f27c0 \
+ --hash=sha256:9a0ff7ee28583ab30a52f371b40f54e7138c52ca67f8ca17ccb7ccf0b383cb5f \
+ --hash=sha256:9ad08547995a57e74fea6abaf5940d399447935faebbd2612b3b0ca6f987946b \
+ --hash=sha256:9b2a4e17bfd68536c3b801800941c95a1d4a06e3cada11c146093ba939d9638d \
+ --hash=sha256:9b78430703cfcf5f5e86eb74027a1ed03a93509273d7c705babb547f03e60016 \
+ --hash=sha256:9d0f92b78cfc3b74a42239fdd8c1266f4715b573204c234d2f9fc3fc7a24f185 \
+ --hash=sha256:9da162b718b12c4219eeeeb68a5b7552fbc7aadedf2efee440f88b9c0e54b45d \
+ --hash=sha256:a00c91104c173c9043bc46f7b30ee5e6d2f6b1149f11f545580f5d6fdff42c0b \
+ --hash=sha256:a029be818059870664157194e46ce0e995082ac49926f1423c1f058534d2aaa9 \
+ --hash=sha256:a1b3db5fae5cbce2131b7420a3f83553d4d89514c03d67804ced36161fe8b6b2 \
+ --hash=sha256:a4cf32a26fa744101b67bfd28c55d992cd19438aff611a46cac7f066afca8fd4 \
+ --hash=sha256:aa0bf113d15e8abdfee92aa4db86761b709a09954083afcb5bf0f952d6065fdb \
+ --hash=sha256:ab47fe727c13c09d0e6f508e3a49e545008e23bf762a245b020391b621f5b726 \
+ --hash=sha256:af22763a0a1eff106426a6e1f13c4582e0d0ad89c1493ab6c058236174cd6c6a \
+ --hash=sha256:af9d4fd79ee1cc8e7caf693ee02737daabfc0fcf2773ca0a4735b356c8ad6f7c \
+ --hash=sha256:b1fef1f13c842a39a03409e30ca0bf87b39a1e2a305a9924deadb75a43105d23 \
+ --hash=sha256:b2eff8ee57c5996b0d2a07c3601fb4ce5fbc37547344a26945dd9e5cbd1ed27a \
+ --hash=sha256:b4c4fbbcff474e1e5f38be1bf04511c03d492d42eec0babda5d03af3b5589374 \
+ --hash=sha256:b8a4131698b6992b2a56015f51646711ec5d893a0b314a4b985477868e240c87 \
+ --hash=sha256:b8a7acf04fda1f30f1007f3cc96d29d8cf0a53e626e4e1655fdf4eabc082d367 \
+ --hash=sha256:ba783541be46f27c8faea5a6645e193943c17ea2f0ffe593639d906a327a9bcc \
+ --hash=sha256:be0744661afbc4099fef7f4e604e7f1ea1be1dd7284f357924af12a705cc7d5c \
+ --hash=sha256:be3964f7312ea05ed283b20f87cb533fdc555b2e428cc7be64612c0b2124f08c \
+ --hash=sha256:be806e2961cd390a89d6c3ce8c2ae34271cfcd05660f716257838bb560f1c3b6 \
+ --hash=sha256:bec77545d188f8bdd29d42bccb9191682a46fb2e655e3d1fb446d47c55ac3b8d \
+ --hash=sha256:c10d92fb6d7fd827e44055fcd932ad93dac6a11e832d51534d77b97d1d85400f \
+ --hash=sha256:c3782fb753aa825b4ccabc04292e07897e2fd941448eabf666856c5530277626 \
+ --hash=sha256:c9ce7a9e967afc0a2af7caa0d15a3e9c1054815f73d6a8cb9225b61921b419bd \
+ --hash=sha256:cb0702c12983be3b2fab98ead349ac63a98216d28dda6f518f52da5498a27a1b \
+ --hash=sha256:cbc619e84a5e3ab2d452de831c88bdcad824414e9c2d28cd101f94dbdf26329c \
+ --hash=sha256:ce4ed8e0c7dbc5b19352b9c2c6131dd23b95fa8698b5cdd076307a33626b72dc \
+ --hash=sha256:ce96ab0bdfcef1b8c371ada2100767ace6804ea35aacce0aef3aeb4f3f499ca8 \
+ --hash=sha256:cf824aceaeffff029ccfba0da637d432ca71ab21f13e7f6f5179cd88ebc77a8a \
+ --hash=sha256:d2a81bdcfde4245468f7030a75a37d50400ac2455c3a4819d9d550c937f90ab5 \
+ --hash=sha256:d2cc2b34f9e1d31ce255174da82902ad75bd7c0d88a33df54a77a22f2ef421ee \
+ --hash=sha256:d2f184336bc1d6abfaaa1262ed42739c3789b1e3a65a29916a615307d22ffd2e \
+ --hash=sha256:d3c622c39f04d5751408f5b801ecb527e6e0a471b367f420a877f7a660d583f6 \
+ --hash=sha256:d7cf5e726b6fa977e428a61880fb108a62f28b6d0c7ef675b117eaff7076df49 \
+ --hash=sha256:d85d784c619370d9329bbd670f41ff5f2ae62ea4519761b679d0f57f0f0ee267 \
+ --hash=sha256:d93ebdb82363d2e7bec64eecdc3632b59e84bd270d74fe5be1659f7787052f9b \
+ --hash=sha256:db8a6313dbac934193fc17fe7610f70cd8181c542a91382531bef5ed785e5615 \
+ --hash=sha256:dbc2ab5d10544eb485baa76c63c501303b716a5c405ff2469a1d8ceffaabf622 \
+ --hash=sha256:dbd749cff1defbde270ca346b69b3baf5f1297213ef322254bf2a28537f0b046 \
+ --hash=sha256:dc662bc9375a6a394b62dfd331874c434819f10ee3902123200dbcf116963f89 \
+ --hash=sha256:dc6b0d5a1ea0318ef2def2b6a55dccf1dcaf77d605672347271ed7b829860765 \
+ --hash=sha256:dc79d192fb76fc0c84f2c58672c17bbbc383fd26c3cdc29daae16ce3d927e8b2 \
+ --hash=sha256:dd2c1d27ebfe6a015cfa2005b7fe8c52d5019f7bbdd801bc6f7499aab9ae739e \
+ --hash=sha256:dea0808153f1fbbad772669d906cddd92100277533a03845de6893cadeffc8be \
+ --hash=sha256:e0d7151a1bd5d0a203a5008fc4ae51a159a610cb82ab0a9b2c4d80241745582e \
+ --hash=sha256:e14aab02258cb776a108107bd15f5b5e4a1bbaa61ef33b36693dfab6f89d54f9 \
+ --hash=sha256:e24d8031a2c62f34853756d9208eeafa6b940a1efcbfe36e8f57d99d52bb7261 \
+ --hash=sha256:e36c80c49853b3ffda7aa1831bf175c13356b210c73128c861f3aa93c3cc4015 \
+ --hash=sha256:e377e4cf8795cdbdff75b8f0223d7b6c68ff4fef36799d88ccf3a995a91c0112 \
+ --hash=sha256:e3acb9c16530362aeaef4e84d57db357002dc5cbfac9a23414c3e73c08301ab2 \
+ --hash=sha256:e3dc8d4ede2dbae6c0fc2b6c958bf51ce9fd7e9b40c0f5b8835c3fde44f5807d \
+ --hash=sha256:e6491658dd2569f05860bad645569145c8626ac231877b0fb2d5f9bcb7054089 \
+ --hash=sha256:eb91d252b35004a84670dfeafadb042528b19842a0080d8b53e5ec1128e8f433 \
+ --hash=sha256:f0396e894bd1e66c74ecbc08b4f6a03dc331140942c4b1d345dd131b68574a60 \
+ --hash=sha256:f09c9d4c26fa79c1bad927efb05aca2391350b8e61c38cbc0d7d3c814e463124 \
+ --hash=sha256:f3cd110e02c5bf17d8fb562f6c9df5c20e73029d587cf8602a2da6c5ef1e32cb \
+ --hash=sha256:f7a37dd208f0d658e0487522078b1ed68cd6bce20ef4b5a915d2809b9094b410 \
+ --hash=sha256:fae4a01ef8c4cb2bbe92ef2063149596907dc4a881a8d26743b3f6b304713171 \
+ --hash=sha256:fc327f4497b7087d06204235199daf208fd01c82d80465dc5efa4ec9df1c5b4e \
+ --hash=sha256:fcc01c57ce6e70b728af02b2401c5bc853a9e14eb07deda30624374f0aebfe42 \
+ --hash=sha256:fde355b02934cc6b07200cc3b27ab0c15870a757d1a72fd401aa92e2ea3c6bfe
+ # via
+ # jsonschema
+ # referencing
+six==1.17.0 \
+ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
+ --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
+ # via -r requirements.in
+tomli==2.2.1 \
+ --hash=sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6 \
+ --hash=sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd \
+ --hash=sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c \
+ --hash=sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b \
+ --hash=sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8 \
+ --hash=sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6 \
+ --hash=sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77 \
+ --hash=sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff \
+ --hash=sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea \
+ --hash=sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192 \
+ --hash=sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249 \
+ --hash=sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee \
+ --hash=sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4 \
+ --hash=sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98 \
+ --hash=sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8 \
+ --hash=sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4 \
+ --hash=sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281 \
+ --hash=sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744 \
+ --hash=sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69 \
+ --hash=sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13 \
+ --hash=sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140 \
+ --hash=sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e \
+ --hash=sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e \
+ --hash=sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc \
+ --hash=sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff \
+ --hash=sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec \
+ --hash=sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2 \
+ --hash=sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222 \
+ --hash=sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106 \
+ --hash=sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272 \
+ --hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \
+ --hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7
+ # via -r requirements.in
+typing-extensions==4.14.1 \
+ --hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \
+ --hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76
+ # via -r requirements.in
+urllib3==2.5.0 \
+ --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \
+ --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc
+ # via
+ # docker
+ # requests
+zstandard==0.24.0 \
+ --hash=sha256:0101f835da7de08375f380192ff75135527e46e3f79bef224e3c49cb640fef6a \
+ --hash=sha256:010302face38c9a909b8934e3bf6038266d6afc69523f3efa023c5cb5d38271b \
+ --hash=sha256:05d27c953f2e0a3ecc8edbe91d6827736acc4c04d0479672e0400ccdb23d818c \
+ --hash=sha256:09887301001e7a81a3618156bc1759e48588de24bddfdd5b7a4364da9a8fbc20 \
+ --hash=sha256:0a416814608610abf5488889c74e43ffa0343ca6cf43957c6b6ec526212422da \
+ --hash=sha256:0a9e95ceb180ccd12a8b3437bac7e8a8a089c9094e39522900a8917745542184 \
+ --hash=sha256:0c9c3cba57f5792532a3df3f895980d47d78eda94b0e5b800651b53e96e0b604 \
+ --hash=sha256:0d66da2649bb0af4471699aeb7a83d6f59ae30236fb9f6b5d20fb618ef6c6777 \
+ --hash=sha256:0dc5654586613aebe5405c1ba180e67b3f29e7d98cf3187c79efdcc172f39457 \
+ --hash=sha256:0ed8345b504df1cab280af923ef69ec0d7d52f7b22f78ec7982fde7c33a43c4f \
+ --hash=sha256:0f6d9a146e07458cb41423ca2d783aefe3a3a97fe72838973c13b8f1ecc7343a \
+ --hash=sha256:10e284748a7e7fbe2815ca62a9d6e84497d34cfdd0143fa9e8e208efa808d7c4 \
+ --hash=sha256:13fc548e214df08d896ee5f29e1f91ee35db14f733fef8eabea8dca6e451d1e2 \
+ --hash=sha256:1b14bc92af065d0534856bf1b30fc48753163ea673da98857ea4932be62079b1 \
+ --hash=sha256:1bda8a85e5b9d5e73af2e61b23609a8cc1598c1b3b2473969912979205a1ff25 \
+ --hash=sha256:1e133a9dd51ac0bcd5fd547ba7da45a58346dbc63def883f999857b0d0c003c4 \
+ --hash=sha256:1f578fab202f4df67a955145c3e3ca60ccaaaf66c97808545b2625efeecdef10 \
+ --hash=sha256:27b6fa72b57824a3f7901fc9cc4ce1c1c834b28f3a43d1d4254c64c8f11149d4 \
+ --hash=sha256:2825a3951f945fb2613ded0f517d402b1e5a68e87e0ee65f5bd224a8333a9a46 \
+ --hash=sha256:2fc67eb15ed573950bc6436a04b3faea6c36c7db98d2db030d48391c6736a0dc \
+ --hash=sha256:337572a7340e1d92fd7fb5248c8300d0e91071002d92e0b8cabe8d9ae7b58159 \
+ --hash=sha256:35f13501a8accf834457d8e40e744568287a215818778bc4d79337af2f3f0d97 \
+ --hash=sha256:388aad2d693707f4a0f6cc687eb457b33303d6b57ecf212c8ff4468c34426892 \
+ --hash=sha256:3aa3b4344b206941385a425ea25e6dd63e5cb0f535a4b88d56e3f8902086be9e \
+ --hash=sha256:3adb4b5414febf074800d264ddf69ecade8c658837a83a19e8ab820e924c9933 \
+ --hash=sha256:3b95fc06489aa9388400d1aab01a83652bc040c9c087bd732eb214909d7fb0dd \
+ --hash=sha256:3f2fe35ec84908dddf0fbf66b35d7c2878dbe349552dd52e005c755d3493d61c \
+ --hash=sha256:3f96a9130171e01dbb6c3d4d9925d604e2131a97f540e223b88ba45daf56d6fb \
+ --hash=sha256:444633b487a711e34f4bccc46a0c5dfbe1aee82c1a511e58cdc16f6bd66f187c \
+ --hash=sha256:498f88f5109666c19531f0243a90d2fdd2252839cd6c8cc6e9213a3446670fa8 \
+ --hash=sha256:51a86bd963de3f36688553926a84e550d45d7f9745bd1947d79472eca27fcc75 \
+ --hash=sha256:52788e7c489069e317fde641de41b757fa0ddc150e06488f153dd5daebac7192 \
+ --hash=sha256:52cd7d9fa0a115c9446abb79b06a47171b7d916c35c10e0c3aa6f01d57561382 \
+ --hash=sha256:55872e818598319f065e8192ebefecd6ac05f62a43f055ed71884b0a26218f41 \
+ --hash=sha256:561123d05681197c0e24eb8ab3cfdaf299e2b59c293d19dad96e1610ccd8fbc6 \
+ --hash=sha256:57be3abb4313e0dd625596376bbb607f40059d801d51c1a1da94d7477e63b255 \
+ --hash=sha256:5e941654cef13a1d53634ec30933722eda11f44f99e1d0bc62bbce3387580d50 \
+ --hash=sha256:622e1e04bd8a085994e02313ba06fbcf4f9ed9a488c6a77a8dbc0692abab6a38 \
+ --hash=sha256:6324fde5cf5120fbf6541d5ff3c86011ec056e8d0f915d8e7822926a5377193a \
+ --hash=sha256:6374feaf347e6b83ec13cc5dcfa70076f06d8f7ecd46cc71d58fac798ff08b76 \
+ --hash=sha256:63d39b161000aeeaa06a1cb77c9806e939bfe460dfd593e4cbf24e6bc717ae94 \
+ --hash=sha256:656ed895b28c7e42dd5b40dfcea3217cfc166b6b7eef88c3da2f5fc62484035b \
+ --hash=sha256:663848a8bac4fdbba27feea2926049fdf7b55ec545d5b9aea096ef21e7f0b079 \
+ --hash=sha256:6885ae4b33aee8835dbdb4249d3dfec09af55e705d74d9b660bfb9da51baaa8b \
+ --hash=sha256:6b005bcee4be9c3984b355336283afe77b2defa76ed6b89332eced7b6fa68b68 \
+ --hash=sha256:76cdfe7f920738ea871f035568f82bad3328cbc8d98f1f6988264096b5264efd \
+ --hash=sha256:77b8b7b98893eaf47da03d262816f01f251c2aa059c063ed8a45c50eada123a5 \
+ --hash=sha256:7ac6e4d727521d86d20ec291a3f4e64a478e8a73eaee80af8f38ec403e77a409 \
+ --hash=sha256:7de5869e616d426b56809be7dc6dba4d37b95b90411ccd3de47f421a42d4d42c \
+ --hash=sha256:869bf13f66b124b13be37dd6e08e4b728948ff9735308694e0b0479119e08ea7 \
+ --hash=sha256:87ae1684bc3c02d5c35884b3726525eda85307073dbefe68c3c779e104a59036 \
+ --hash=sha256:8ecd3b1f7a601f79e0cd20c26057d770219c0dc2f572ea07390248da2def79a4 \
+ --hash=sha256:92be52ca4e6e604f03d5daa079caec9e04ab4cbf6972b995aaebb877d3d24e13 \
+ --hash=sha256:92ea7855d5bcfb386c34557516c73753435fb2d4a014e2c9343b5f5ba148b5d8 \
+ --hash=sha256:962ea3aecedcc944f8034812e23d7200d52c6e32765b8da396eeb8b8ffca71ce \
+ --hash=sha256:98ca91dc9602cf351497d5600aa66e6d011a38c085a8237b370433fcb53e3409 \
+ --hash=sha256:9b84c6c210684286e504022d11ec294d2b7922d66c823e87575d8b23eba7c81f \
+ --hash=sha256:a0f6fc2ea6e07e20df48752e7700e02e1892c61f9a6bfbacaf2c5b24d5ad504b \
+ --hash=sha256:a2bda8f2790add22773ee7a4e43c90ea05598bffc94c21c40ae0a9000b0133c3 \
+ --hash=sha256:aa705beb74ab116563f4ce784fa94771f230c05d09ab5de9c397793e725bb1db \
+ --hash=sha256:aadf32c389bb7f02b8ec5c243c38302b92c006da565e120dfcb7bf0378f4f848 \
+ --hash=sha256:ab2357353894a5ec084bb8508ff892aa43fb7fe8a69ad310eac58221ee7f72aa \
+ --hash=sha256:ad9fd176ff6800a0cf52bcf59c71e5de4fa25bf3ba62b58800e0f84885344d34 \
+ --hash=sha256:addfc23e3bd5f4b6787b9ca95b2d09a1a67ad5a3c318daaa783ff90b2d3a366e \
+ --hash=sha256:af1394c2c5febc44e0bbf0fc6428263fa928b50d1b1982ce1d870dc793a8e5f4 \
+ --hash=sha256:b04c94718f7a8ed7cdd01b162b6caa1954b3c9d486f00ecbbd300f149d2b2606 \
+ --hash=sha256:b4f20417a4f511c656762b001ec827500cbee54d1810253c6ca2df2c0a307a5f \
+ --hash=sha256:b7a8c30d9bf4bd5e4dcfe26900bef0fcd9749acde45cdf0b3c89e2052fda9a13 \
+ --hash=sha256:b7fa260dd2731afd0dfa47881c30239f422d00faee4b8b341d3e597cface1483 \
+ --hash=sha256:b91380aefa9c7ac831b011368daf378d3277e0bdeb6bad9535e21251e26dd55a \
+ --hash=sha256:bb2446a55b3a0fd8aa02aa7194bd64740015464a2daaf160d2025204e1d7c282 \
+ --hash=sha256:bc05f8a875eb651d1cc62e12a4a0e6afa5cd0cc231381adb830d2e9c196ea895 \
+ --hash=sha256:bcf69e0bcddbf2adcfafc1a7e864edcc204dd8171756d3a8f3340f6f6cc87b7b \
+ --hash=sha256:bf02f915fa7934ea5dfc8d96757729c99a8868b7c340b97704795d6413cf5fe6 \
+ --hash=sha256:c39d2b6161f3c5c5d12e9207ecf1006bb661a647a97a6573656b09aaea3f00ef \
+ --hash=sha256:c59740682a686bf835a1a4d8d0ed1eefe31ac07f1c5a7ed5f2e72cf577692b00 \
+ --hash=sha256:cc76de75300f65b8eb574d855c12518dc25a075dadb41dd18f6322bda3fe15d5 \
+ --hash=sha256:cd0d3d16e63873253bad22b413ec679cf6586e51b5772eb10733899832efec42 \
+ --hash=sha256:cda61c46343809ecda43dc620d1333dd7433a25d0a252f2dcc7667f6331c7b61 \
+ --hash=sha256:cf7fbb4e54136e9a03c7ed7691843c4df6d2ecc854a2541f840665f4f2bb2edd \
+ --hash=sha256:d2b3b4bda1a025b10fe0269369475f420177f2cb06e0f9d32c95b4873c9f80b8 \
+ --hash=sha256:d5e3b9310fd7f0d12edc75532cd9a56da6293840c84da90070d692e0bb15f186 \
+ --hash=sha256:d64899cc0f33a8f446f1e60bffc21fa88b99f0e8208750d9144ea717610a80ce \
+ --hash=sha256:d6975f2d903bc354916a17b91a7aaac7299603f9ecdb788145060dde6e573a16 \
+ --hash=sha256:d82ac87017b734f2fb70ff93818c66f0ad2c3810f61040f077ed38d924e19980 \
+ --hash=sha256:dd91b0134a32dfcd8be504e8e46de44ad0045a569efc25101f2a12ccd41b5759 \
+ --hash=sha256:df4be1cf6e8f0f2bbe2a3eabfff163ef592c84a40e1a20a8d7db7f27cfe08fc2 \
+ --hash=sha256:e05d66239d14a04b4717998b736a25494372b1b2409339b04bf42aa4663bf251 \
+ --hash=sha256:e40cd0fc734aa1d4bd0e7ad102fd2a1aefa50ce9ef570005ffc2273c5442ddc3 \
+ --hash=sha256:e46eb6702691b24ddb3e31e88b4a499e31506991db3d3724a85bd1c5fc3cfe4e \
+ --hash=sha256:e4ebb000c0fe24a6d0f3534b6256844d9dbf042fdf003efe5cf40690cf4e0f3e \
+ --hash=sha256:e69f8e534b4e254f523e2f9d4732cf9c169c327ca1ce0922682aac9a5ee01155 \
+ --hash=sha256:e91a4e5d62da7cb3f53e04fe254f1aa41009af578801ee6477fe56e7bef74ee2 \
+ --hash=sha256:ec194197e90ca063f5ecb935d6c10063d84208cac5423c07d0f1a09d1c2ea42b \
+ --hash=sha256:f6ae9fc67e636fc0fa9adee39db87dfbdeabfa8420bc0e678a1ac8441e01b22b \
+ --hash=sha256:f7d3fe9e1483171e9183ffdb1fab07c5fef80a9c3840374a38ec2ab869ebae20 \
+ --hash=sha256:fdc7a52a4cdaf7293e10813fd6a3abc0c7753660db12a3b864ab1fb5a0c60c16 \
+ --hash=sha256:fe3198b81c00032326342d973e526803f183f97aa9e9a98e3f897ebafe21178f \
+ --hash=sha256:ff19efaa33e7f136fe95f9bbcc90ab7fb60648453b03f95d1de3ab6997de0f32
+ # via -r requirements.in
From 049bef042e3a4ac38588314426a4185fcba8deca Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Mon, 18 Aug 2025 06:54:38 -0700
Subject: [PATCH 60/72] docs: Move libX11 / PyQt stuff to "former quirks"
(#739)
This has been working fine since May 2022....
---
docs/quirks.rst | 68 ++++++++-----------------------------------------
1 file changed, 10 insertions(+), 58 deletions(-)
diff --git a/docs/quirks.rst b/docs/quirks.rst
index f24886a..84b2e1e 100644
--- a/docs/quirks.rst
+++ b/docs/quirks.rst
@@ -142,64 +142,6 @@ Some functionality may behave subtly differently as a result of our choice
to link ``libedit`` by default. (We choose ``libedit`` by default to
avoid GPL licensing requirements of ``readline``.)
-.. _quirk_linux_libx11:
-
-Static Linking of ``libX11`` / Incompatibility with PyQt on Linux
-=================================================================
-
-The ``_tkinter`` Python extension module in the Python standard library
-statically links against ``libX11``, ``libxcb``, and ``libXau`` on Linux.
-In addition, the ``_tkinter`` extension module is statically linked into
-``libpython`` and isn't a standalone shared library file. This effectively
-means that all these X11 libraries are statically linked into the main
-Python interpreter.
-
-On typical builds of Python on Linux, ``_tkinter`` will link against
-external shared libraries. e.g.::
-
- $ ldd /usr/lib/python3.9/lib-dynload/_tkinter.cpython-39-x86_64-linux-gnu.so
- linux-vdso.so.1 (0x00007fff3be9d000)
- libBLT.2.5.so.8.6 => /lib/libBLT.2.5.so.8.6 (0x00007fdb6a6f8000)
- libtk8.6.so => /lib/x86_64-linux-gnu/libtk8.6.so (0x00007fdb6a584000)
- libtcl8.6.so => /lib/x86_64-linux-gnu/libtcl8.6.so (0x00007fdb6a3c1000)
- libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdb6a1d5000)
- libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007fdb6a097000)
- libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdb69f49000)
- libXft.so.2 => /lib/x86_64-linux-gnu/libXft.so.2 (0x00007fdb69f2e000)
- libfontconfig.so.1 => /lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007fdb69ee6000)
- libXss.so.1 => /lib/x86_64-linux-gnu/libXss.so.1 (0x00007fdb69ee1000)
- libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fdb69eda000)
- libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fdb69ebe000)
- libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fdb69e9c000)
- /lib64/ld-linux-x86-64.so.2 (0x00007fdb6a892000)
- libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fdb69e70000)
- libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007fdb69dad000)
- libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fdb69da0000)
- libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fdb69d71000)
- libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007fdb69d68000)
- libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x00007fdb69d53000)
- libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007fdb69d4b000)
- libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fdb69d43000)
- libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16 (0x00007fdb69d08000)
- libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007fdb69cfa000)
- libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fdb69ce2000)
- libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007fdb69cbd000)
- libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x00007fdb69cb0000)
-
-The static linking of ``libX11`` and other libraries can cause problems when
-3rd party Python extension modules also loading similar libraries are also
-loaded into the process. For example, extension modules associated with ``PyQt``
-are known to link against a shared ``libX11.so.6``. If multiple versions of
-``libX11`` are loaded into the same process, run-time crashes / segfaults can
-occur. See e.g. https://github.com/astral-sh/python-build-standalone/issues/95.
-
-The conceptual workaround is to not statically link ``libX11`` and similar
-libraries into ``libpython``. However, this requires re-linking a custom
-``libpython`` without ``_tkinter``. It is possible to do this with the object
-files included in the distributions. But there isn't a turnkey way to do this.
-And you can't easily remove ``_tkinter`` and its symbols from the pre-built
-and ready-to-use Python install included in this project's distribution
-artifacts.
.. _quirk_references_to_build_paths:
@@ -254,6 +196,7 @@ make distributions more portable, please file a GitHub issue.
.. _quirk_former:
.. _quirk_missing_libcrypt:
+.. _quirk_linux_libx11:
Former quirks
=============
@@ -283,4 +226,13 @@ been resolved.
New in Python 3.13`_ about third-party replacements for the ``crypt``
module.
+* "Static Linking of ``libX11`` / Incompatibility with PyQt on Linux":
+ The 20220318 release and earlier exported dynamic symbols for the
+ internal, statically-linked build of ``libX11`` and other libraries.
+ These would cause conflicts and potential crashes when using
+ third-party extension modules such as PyQt that load an actual shared
+ ``libX11`` library (usually provided by your OS). Starting with the
+ 20220502 release, symbols from internal dependencies are no longer
+ exported.
+
.. _What's New in Python 3.13: https://docs.python.org/3/whatsnew/3.13.html#whatsnew313-pep594
From 6e9f3165c8a720cfc61232460ed5b62a583c3900 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Mon, 18 Aug 2025 13:56:36 -0500
Subject: [PATCH 61/72] Display zstd threading bounds on failure and fix assert
for 32-bin Windows (#770)
---
src/verify_distribution.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/verify_distribution.py b/src/verify_distribution.py
index 62e787b..2a9abda 100644
--- a/src/verify_distribution.py
+++ b/src/verify_distribution.py
@@ -179,7 +179,10 @@ def test_gil_disabled(self):
def test_zstd_multithreaded(self):
from compression import zstd
- assert zstd.CompressionParameter.nb_workers.bounds() == (0, 256)
+ max_threads = zstd.CompressionParameter.nb_workers.bounds()[1]
+ assert max_threads > 0, (
+ "Expected multithreading to be enabled but max threads is zero"
+ )
@unittest.skipIf("TCL_LIBRARY" not in os.environ, "TCL_LIBRARY not set")
@unittest.skipIf("DISPLAY" not in os.environ, "DISPLAY not set")
From 735ded8fb99f9b5bebd397a88c57d030e924b63e Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Mon, 18 Aug 2025 16:23:35 -0500
Subject: [PATCH 62/72] Replace `setup-just` with `setup-crate` (#771)
The former is just a composite of a latter, but does not pin to a commit
so it violates our policy. I do not think `setup-crate` supports pinning
a just commit, so I think we will want to just drop the whole action in
the future.
See
- https://github.com/astral-sh/python-build-standalone/issues/760
- https://github.com/extractions/setup-just/issues/20
- https://github.com/extractions/setup-just/issues/23
See failure at
https://github.com/astral-sh/python-build-standalone/actions/runs/17052072811/attempts/1
---
.github/workflows/release.yml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 0a77d11..c3b3225 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -40,7 +40,10 @@ jobs:
submodules: recursive
persist-credentials: true # needed for git operations below
- - uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v2
+ - uses: extractions/setup-crate@4993624604c307fbca528d28a3c8b60fa5ecc859 # v1.4.0
+ with:
+ repo: casey/just
+ version: 1.42.4
# Perform a release in dry-run mode.
- run: just release-dry-run ${GH_TOKEN} ${GITHUB_EVENT_INPUTS_SHA} ${GITHUB_EVENT_INPUTS_TAG}
From fd9784e6b0e8a18c883fa46a5d177a7888a03132 Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Thu, 28 Aug 2025 07:53:22 -0500
Subject: [PATCH 63/72] Add support for aarch64 musl (#569)
Closes #87
Does not include the `+static` variant as I was having a hard time
getting the bzip2 build passing. I'll open a new issue to track that.
Related https://github.com/astral-sh/python-build-standalone/pull/484
---
ci-targets.yaml | 20 +++++++++++++
cpython-unix/build-cpython-host.sh | 5 ++++
cpython-unix/build-cpython.sh | 10 +++++--
cpython-unix/build-zstd.sh | 34 +++++++++++++++++----
cpython-unix/build.py | 5 ++++
cpython-unix/targets.yml | 47 ++++++++++++++++++++++++++++++
src/release.rs | 12 ++++++++
src/validation.rs | 7 +++++
8 files changed, 132 insertions(+), 8 deletions(-)
diff --git a/ci-targets.yaml b/ci-targets.yaml
index c59d5b7..492b815 100644
--- a/ci-targets.yaml
+++ b/ci-targets.yaml
@@ -348,6 +348,26 @@ linux:
minimum-python-version: "3.13"
run: true
+ aarch64-unknown-linux-musl:
+ arch: aarch64
+ libc: musl
+ python_versions:
+ - "3.9"
+ - "3.10"
+ - "3.11"
+ - "3.12"
+ - "3.13"
+ - "3.14"
+ build_options:
+ # TODO: Static support is current blocked by some compiler-rt linking issues
+ # - debug+static
+ # - noopt+static
+ # - lto+static
+ - debug
+ - noopt
+ - lto
+ run: true
+
windows:
i686-pc-windows-msvc:
arch: x86
diff --git a/cpython-unix/build-cpython-host.sh b/cpython-unix/build-cpython-host.sh
index 99b021d..ff7c3a4 100755
--- a/cpython-unix/build-cpython-host.sh
+++ b/cpython-unix/build-cpython-host.sh
@@ -70,6 +70,11 @@ case "${BUILD_TRIPLE}" in
EXTRA_HOST_CPPFLAGS="${EXTRA_HOST_CPPFLAGS} -I/usr/include/x86_64-linux-gnu"
EXTRA_HOST_LDFLAGS="${EXTRA_HOST_LDFLAGS} -L/usr/lib/x86_64-linux-gnu"
;;
+ aarch64-unknown-linux-gnu)
+ EXTRA_HOST_CFLAGS="${EXTRA_HOST_CFLAGS} -I/usr/include/aarch64-linux-gnu"
+ EXTRA_HOST_CPPFLAGS="${EXTRA_HOST_CPPFLAGS} -I/usr/include/aarch64-linux-gnu"
+ EXTRA_HOST_LDFLAGS="${EXTRA_HOST_LDFLAGS} -L/usr/lib/aarch64-linux-gnu"
+ ;;
*)
;;
esac
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index 658395a..30b0d2b 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -1077,8 +1077,14 @@ touch "${LIB_DYNLOAD}/.empty"
# Symlink libpython so we don't have 2 copies.
case "${TARGET_TRIPLE}" in
-aarch64-unknown-linux-gnu)
- PYTHON_ARCH="aarch64-linux-gnu"
+aarch64-unknown-linux-*)
+ # In Python 3.13+, the musl target is identified in cross compiles and the output directory
+ # is named accordingly.
+ if [[ "${CC}" = "musl-clang" && -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]]; then
+ PYTHON_ARCH="aarch64-linux-musl"
+ else
+ PYTHON_ARCH="aarch64-linux-gnu"
+ fi
;;
# This is too aggressive. But we don't have patches in place for
# setting the platform name properly on non-Darwin.
diff --git a/cpython-unix/build-zstd.sh b/cpython-unix/build-zstd.sh
index 5a889da..bcce804 100755
--- a/cpython-unix/build-zstd.sh
+++ b/cpython-unix/build-zstd.sh
@@ -15,16 +15,20 @@ tar -xf zstd-${ZSTD_VERSION}.tar.gz
pushd cpython-source-deps-zstd-${ZSTD_VERSION}/lib
if [ "${CC}" = "musl-clang" ]; then
- # In order to build the library with SSE2, BMI, and AVX2 intrinstics, we need musl-clang to find
+ # In order to build the library with intrinsics, we need musl-clang to find
# headers that provide access to the intrinsics, as they are not provided by musl. These are
# part of the include files that are part of clang. But musl-clang eliminates them from the
# default include path. So copy them into place.
- for h in ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/include/*intrin.h ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/include/{__wmmintrin_aes.h,__wmmintrin_pclmul.h,emmintrin.h,immintrin.h,mm_malloc.h}; do
+ for h in ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/include/*intrin.h ${TOOLS_PATH}/${TOOLCHAIN}/lib/clang/*/include/{__wmmintrin_aes.h,__wmmintrin_pclmul.h,emmintrin.h,immintrin.h,mm_malloc.h,arm_neon.h,arm_neon_sve_bridge.h,arm_bf16.h,arm_fp16.h,arm_acle.h,arm_vector_types.h}; do
filename=$(basename "$h")
- if [ -e "${TOOLS_PATH}/host/include/${filename}" ]; then
- echo "warning: ${filename} already exists"
+ if [ -f "$h" ]; then
+ if [ -e "${TOOLS_PATH}/host/include/${filename}" ]; then
+ echo "warning: ${filename} already exists"
+ fi
+ cp "$h" ${TOOLS_PATH}/host/include/
+ else
+ echo "warning: ${filename} not found (skipping)"
fi
- cp "$h" ${TOOLS_PATH}/host/include/
done
EXTRA_TARGET_CFLAGS="${EXTRA_TARGET_CFLAGS} -I${TOOLS_PATH}/host/include/"
@@ -33,7 +37,7 @@ if [ "${CC}" = "musl-clang" ]; then
# `qsort_r` is actually available so we patch it to include a check for glibc.
patch -p1 <suffix, ctx->suffixSize, sizeof(U32),
ctx,
diff --git a/cpython-unix/build.py b/cpython-unix/build.py
index ea44c29..138a9c9 100755
--- a/cpython-unix/build.py
+++ b/cpython-unix/build.py
@@ -88,6 +88,11 @@ def add_target_env(env, build_platform, target_triple, build_env):
extra_host_cflags = []
extra_host_ldflags = []
+ # Add compiler-rt for aarch64-musl to resolve missing builtins
+ if target_triple == "aarch64-unknown-linux-musl":
+ extra_target_cflags.append("--rtlib=compiler-rt")
+ extra_target_ldflags.append("--rtlib=compiler-rt")
+
if build_platform.startswith("linux_"):
machine = platform.machine()
diff --git a/cpython-unix/targets.yml b/cpython-unix/targets.yml
index d0ef4a7..451b984 100644
--- a/cpython-unix/targets.yml
+++ b/cpython-unix/targets.yml
@@ -1131,3 +1131,50 @@ x86_64_v4-unknown-linux-musl:
- zlib
- zstd
openssl_target: linux-x86_64
+
+aarch64-unknown-linux-musl:
+ host_platforms:
+ - linux_x86_64
+ - linux_aarch64
+ pythons_supported:
+ - '3.9'
+ - '3.10'
+ - '3.11'
+ - '3.12'
+ - '3.13'
+ - '3.14'
+ needs_toolchain: true
+ docker_image_suffix: .debian9
+ needs_toolchain: true
+ host_cc: clang
+ host_cxx: clang++
+ target_cc: musl-clang
+ target_cxx: clang++
+ target_cflags:
+ - '-fvisibility=hidden'
+ needs:
+ - autoconf
+ - bdb
+ - binutils
+ - bzip2
+ - expat
+ - libedit
+ - libffi-3.3
+ - libX11
+ - libXau
+ - libxcb
+ - m4
+ - mpdecimal
+ - musl
+ - ncurses
+ - openssl-3.0
+ - patchelf
+ - sqlite
+ - tcl
+ - tk
+ - uuid
+ - xorgproto
+ - xz
+ - zlib
+ - zstd
+ openssl_target: linux-aarch64
diff --git a/src/release.rs b/src/release.rs
index 0b67888..4c123f6 100644
--- a/src/release.rs
+++ b/src/release.rs
@@ -339,6 +339,18 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy::
}],
},
);
+ h.insert(
+ "aarch64-unknown-linux-musl",
+ TripleRelease {
+ suffixes: vec!["debug", "lto", "noopt"],
+ install_only_suffix: "lto",
+ python_version_requirement: None,
+ conditional_suffixes: vec![ConditionalSuffixes {
+ python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
+ suffixes: linux_suffixes_musl_freethreaded.clone(),
+ }],
+ },
+ );
h
});
diff --git a/src/validation.rs b/src/validation.rs
index 6d9b5db..163e7b0 100644
--- a/src/validation.rs
+++ b/src/validation.rs
@@ -35,6 +35,7 @@ const RECOGNIZED_TRIPLES: &[&str] = &[
"aarch64-apple-ios",
"aarch64-pc-windows-msvc",
"aarch64-unknown-linux-gnu",
+ "aarch64-unknown-linux-musl",
"armv7-unknown-linux-gnueabi",
"armv7-unknown-linux-gnueabihf",
"arm64-apple-tvos",
@@ -211,6 +212,10 @@ static GLIBC_MAX_VERSION_BY_TRIPLE: Lazy> = Lazy:
("aarch64-apple-ios", "iOS-aarch64"),
("aarch64-pc-windows-msvc", "win-arm64"),
("aarch64-unknown-linux-gnu", "linux-aarch64"),
+ ("aarch64-unknown-linux-musl", "linux-aarch64"),
("armv7-unknown-linux-gnueabi", "linux-arm"),
("armv7-unknown-linux-gnueabihf", "linux-arm"),
("i686-pc-windows-msvc", "win32"),
@@ -949,6 +955,7 @@ fn validate_elf>(
let wanted_cpu_type = match target_triple {
"aarch64-unknown-linux-gnu" => object::elf::EM_AARCH64,
+ "aarch64-unknown-linux-musl" => object::elf::EM_AARCH64,
"armv7-unknown-linux-gnueabi" => object::elf::EM_ARM,
"armv7-unknown-linux-gnueabihf" => object::elf::EM_ARM,
"i686-unknown-linux-gnu" => object::elf::EM_386,
From aa32d4a419f6c5d1c5c341d1610464f4f651835c Mon Sep 17 00:00:00 2001
From: Zanie Blue
Date: Thu, 28 Aug 2025 11:44:26 -0500
Subject: [PATCH 64/72] Include freethreaded variants of `aarch64-*-musl`
(#778)
---
ci-targets.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ci-targets.yaml b/ci-targets.yaml
index 492b815..0662bbe 100644
--- a/ci-targets.yaml
+++ b/ci-targets.yaml
@@ -366,6 +366,12 @@ linux:
- debug
- noopt
- lto
+ build_options_conditional:
+ - options:
+ - freethreaded+debug
+ - freethreaded+noopt
+ - freethreaded+lto
+ minimum-python-version: "3.13"
run: true
windows:
From 4ec8e29e90d5e42df6b745e5827d7f44f0af17f9 Mon Sep 17 00:00:00 2001
From: Christian Clauss
Date: Thu, 28 Aug 2025 23:31:19 +0200
Subject: [PATCH 65/72] Fix typos discovered by codespell (#779)
% `codespell --ignore-words-list=inout
--skip="LICENSE.*,python-licenses.rst" --write-changes`
* https://pypi.org/project/codespell
---
cpython-unix/build-cpython.sh | 2 +-
cpython-unix/build-libffi.sh | 4 ++--
cpython-unix/build.py | 2 +-
cpython-windows/build.py | 2 +-
docs/building.rst | 2 +-
docs/distributions.rst | 4 ++--
src/validation.rs | 2 +-
7 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index 30b0d2b..e3188aa 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -460,7 +460,7 @@ if [ -n "${CPYTHON_OPTIMIZED}" ]; then
if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]]; then
# Do not enable on x86-64 macOS because the JIT requires macOS 11+ and we are currently
- # using 10.15 as a miniumum version.
+ # using 10.15 as a minimum version.
# Do not enable when free-threading, because they're not compatible yet.
if [[ ! ( "${TARGET_TRIPLE}" == "x86_64-apple-darwin" || -n "${CPYTHON_FREETHREADED}" ) ]]; then
CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --enable-experimental-jit=yes-off"
diff --git a/cpython-unix/build-libffi.sh b/cpython-unix/build-libffi.sh
index 9b18802..562d4d5 100755
--- a/cpython-unix/build-libffi.sh
+++ b/cpython-unix/build-libffi.sh
@@ -225,7 +225,7 @@ index 60cfa50..6a9a561 100644
BTI_C
- /* Sign the lr with x1 since that is where it will be stored */
+ PAC_CFI_WINDOW_SAVE
-+ /* Sign the lr with x1 since that is the CFA which is the modifer used in auth instructions */
++ /* Sign the lr with x1 since that is the CFA which is the modifier used in auth instructions */
SIGN_LR_WITH_REG(x1)
- /* Use a stack frame allocated by our caller. */
@@ -352,7 +352,7 @@ index 6a9a561..e83bc65 100644
+ cfi_startproc
BTI_C
PAC_CFI_WINDOW_SAVE
- /* Sign the lr with x1 since that is the CFA which is the modifer used in auth instructions */
+ /* Sign the lr with x1 since that is the CFA which is the modifier used in auth instructions */
@@ -348,8 +348,8 @@ CNAME(ffi_closure_SYSV_V):
#endif
diff --git a/cpython-unix/build.py b/cpython-unix/build.py
index 138a9c9..c5d73a1 100755
--- a/cpython-unix/build.py
+++ b/cpython-unix/build.py
@@ -517,7 +517,7 @@ def python_build_info(
bi["object_file_format"] = object_file_format
- # Determine allowed libaries on Linux
+ # Determine allowed libraries on Linux
libs = extra_metadata["python_config_vars"].get("LIBS", "").split()
mips = target_triple.split("-")[0] in {"mips", "mipsel"}
linux_allowed_system_libraries = LINUX_ALLOW_SYSTEM_LIBRARIES.copy()
diff --git a/cpython-windows/build.py b/cpython-windows/build.py
index 8f8cc43..5fce1ab 100644
--- a/cpython-windows/build.py
+++ b/cpython-windows/build.py
@@ -1576,7 +1576,7 @@ def build_cpython(
# import their contents. According to
# https://github.com/pypa/pip/issues/11146 running pip from a wheel is not
# supported. But it has historically worked and is simple. So do this until
- # it stops working and we need to switch to running pip from the filesytem.
+ # it stops working and we need to switch to running pip from the filesystem.
pip_env = dict(os.environ)
pip_env["PYTHONPATH"] = str(pip_wheel)
diff --git a/docs/building.rst b/docs/building.rst
index c6a07e2..605f5f0 100644
--- a/docs/building.rst
+++ b/docs/building.rst
@@ -87,7 +87,7 @@ Visual Studio 2017 (or later) is required. A compatible Windows SDK is required
(10.0.17763.0 as per CPython 3.7.2).
* A ``git.exe`` on ``PATH`` (to clone ``libffi`` from source).
-* An installation of Cywgin with the ``autoconf``, ``automake``, ``libtool``,
+* An installation of Cygwin with the ``autoconf``, ``automake``, ``libtool``,
and ``make`` packages installed. (``libffi`` build dependency.)
To build a dynamically linked Python distribution for Windows x64::
diff --git a/docs/distributions.rst b/docs/distributions.rst
index 9e4cf83..16fb238 100644
--- a/docs/distributions.rst
+++ b/docs/distributions.rst
@@ -112,7 +112,7 @@ python_implementation_cache_tag
(Version 5 or above only.)
python_implementation_hex_version
- Hexidecimal expression of implementation version.
+ Hexadecimal expression of implementation version.
This is the value exposed by ``sys.implementation.hexversion``.
@@ -237,7 +237,7 @@ python_suffixes
(Version 5 or above only.)
python_bytecode_magic_number
- Magic number to use for bytecode files, expressed as a hexidecimal
+ Magic number to use for bytecode files, expressed as a hexadecimal
string.
(Version 5 or above only.)
diff --git a/src/validation.rs b/src/validation.rs
index 163e7b0..2fd4786 100644
--- a/src/validation.rs
+++ b/src/validation.rs
@@ -593,7 +593,7 @@ const ELF_BANNED_SYMBOLS: &[&str] = &[
/// The list is obviously not complete.
const DEPENDENCY_PACKAGE_SYMBOLS: &[&str] = &[
/* TODO(geofft): Tk provides these as no-op stubs on macOS, make it
- * stop doing that so we can reenable the check
+ * stop doing that so we can re-enable the check
* // libX11
* "XClearWindow",
* "XFlush",
From 1b4757c766e6182868a3745c2e776be03c5707e2 Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Tue, 2 Sep 2025 08:21:56 -0400
Subject: [PATCH 66/72] On macOS, add 64 bytes of headerpad to accommodate code
signatures (#780)
Closes #749.
---
cpython-unix/build-cpython.sh | 10 ++++++++++
src/validation.rs | 34 ++++++++++++++++++++++++++++++++--
2 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index e3188aa..d21533a 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -365,6 +365,16 @@ if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_12}" && "${TARGET_TRIPLE}" = "ppc64le
LDFLAGS="${LDFLAGS} -Wl,--no-tls-get-addr-optimize"
fi
+# We're calling install_name_tool -add_rpath on extension modules, which
+# eats up 0x20 bytes of space in the Mach-O header, and we need to make
+# sure there's still enough room to add a code signature (0x10 bytes) on
+# non-arm64 where there's no automatic ad-hoc signature. We are somehow
+# on a toolchain that doesn't make sure there's enough space by default
+# so give it plenty of space.
+if [[ "${PYBUILD_PLATFORM}" = macos* ]]; then
+ LDFLAGS="${LDFLAGS} -Wl,-headerpad,40"
+fi
+
CPPFLAGS=$CFLAGS
CONFIGURE_FLAGS="
diff --git a/src/validation.rs b/src/validation.rs
index 2fd4786..33e61e2 100644
--- a/src/validation.rs
+++ b/src/validation.rs
@@ -12,10 +12,10 @@ use {
FileHeader32, FileHeader64, ET_DYN, ET_EXEC, SHN_UNDEF, STB_GLOBAL, STB_WEAK, STV_DEFAULT,
STV_HIDDEN,
},
- macho::{MachHeader32, MachHeader64, MH_OBJECT, MH_TWOLEVEL},
+ macho::{LC_CODE_SIGNATURE, MH_OBJECT, MH_TWOLEVEL, MachHeader32, MachHeader64},
read::{
elf::{Dyn, FileHeader, SectionHeader, Sym},
- macho::{LoadCommandVariant, MachHeader, Nlist},
+ macho::{LoadCommandVariant, MachHeader, Nlist, Section, Segment},
pe::{ImageNtHeaders, PeFile, PeFile32, PeFile64},
},
Architecture, Endianness, FileKind, Object, SectionIndex, SymbolScope,
@@ -1264,6 +1264,8 @@ fn validate_macho>(
let mut undefined_symbols = vec![];
let mut target_version = None;
let mut sdk_version = None;
+ let mut has_code_signature = false;
+ let mut lowest_file_offset = u64::MAX;
while let Some(load_command) = load_commands.next()? {
match load_command.variant()? {
@@ -1386,10 +1388,38 @@ fn validate_macho>(
}
}
}
+ LoadCommandVariant::Segment32(segment, segment_data) => {
+ for section in segment.sections(endian, segment_data)? {
+ if let Some((offset, _)) = section.file_range(endian) {
+ lowest_file_offset = lowest_file_offset.min(offset);
+ }
+ }
+ }
+ LoadCommandVariant::Segment64(segment, segment_data) => {
+ for section in segment.sections(endian, segment_data)? {
+ if let Some((offset, _)) = section.file_range(endian) {
+ lowest_file_offset = lowest_file_offset.min(offset);
+ }
+ }
+ }
+ LoadCommandVariant::LinkeditData(c) if c.cmd.get(endian) == LC_CODE_SIGNATURE => {
+ has_code_signature = true;
+ }
_ => {}
}
}
+ let end_of_load_commands =
+ std::mem::size_of_val(header) as u64 + header.sizeofcmds(endian) as u64;
+ if header.filetype(endian) != MH_OBJECT
+ && end_of_load_commands + if has_code_signature { 0 } else { 16 } > lowest_file_offset
+ {
+ context.errors.push(format!(
+ "{}: Insufficient headerpad between end of load commands {end_of_load_commands:#x} and beginning of code {lowest_file_offset:#x}",
+ path.display(),
+ ));
+ }
+
if let Some(actual_target_version) = target_version {
if actual_target_version != advertised_target_version {
context.errors.push(format!(
From bcf094340b9647387b0bb795104117b68e931409 Mon Sep 17 00:00:00 2001
From: Geoffrey Thomas
Date: Tue, 2 Sep 2025 09:57:52 -0400
Subject: [PATCH 67/72] Update SQLite to 3.50.4 (#786)
Fixes #784.
---
pythonbuild/downloads.py | 10 +++++-----
src/verify_distribution.py | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/pythonbuild/downloads.py b/pythonbuild/downloads.py
index 4332d68..e1562c0 100644
--- a/pythonbuild/downloads.py
+++ b/pythonbuild/downloads.py
@@ -295,11 +295,11 @@
},
# Remember to update verify_distribution.py when version changed.
"sqlite": {
- "url": "https://www.sqlite.org/2025/sqlite-autoconf-3490100.tar.gz",
- "size": 3226385,
- "sha256": "106642d8ccb36c5f7323b64e4152e9b719f7c0215acf5bfeac3d5e7f97b59254",
- "version": "3490100",
- "actual_version": "3.49.1.0",
+ "url": "https://www.sqlite.org/2025/sqlite-autoconf-3500400.tar.gz",
+ "size": 3173050,
+ "sha256": "a3db587a1b92ee5ddac2f66b3edb41b26f9c867275782d46c3a088977d6a5b18",
+ "version": "3500400",
+ "actual_version": "3.50.4.0",
"library_names": ["sqlite3"],
"licenses": [],
"license_file": "LICENSE.sqlite.txt",
diff --git a/src/verify_distribution.py b/src/verify_distribution.py
index 2a9abda..62d58f9 100644
--- a/src/verify_distribution.py
+++ b/src/verify_distribution.py
@@ -114,7 +114,7 @@ def test_hashlib(self):
def test_sqlite(self):
import sqlite3
- self.assertEqual(sqlite3.sqlite_version_info, (3, 49, 1))
+ self.assertEqual(sqlite3.sqlite_version_info, (3, 50, 4))
# Optional SQLite3 features are enabled.
conn = sqlite3.connect(":memory:")
From 779d39db776101e7cd3df121ed220cc491107057 Mon Sep 17 00:00:00 2001
From: vSecurity Bot <112028320+vsecurity-github-bot@users.noreply.github.com>
Date: Wed, 18 Sep 2024 11:30:44 -0700
Subject: [PATCH 68/72] Install Security PR Check GitHub Action
---
.github/workflows/security-3rd-party-pr-checks.yml | 10 ++++++++++
1 file changed, 10 insertions(+)
create mode 100644 .github/workflows/security-3rd-party-pr-checks.yml
diff --git a/.github/workflows/security-3rd-party-pr-checks.yml b/.github/workflows/security-3rd-party-pr-checks.yml
new file mode 100644
index 0000000..5337dab
--- /dev/null
+++ b/.github/workflows/security-3rd-party-pr-checks.yml
@@ -0,0 +1,10 @@
+name: security-3rd-party-pr-checks
+on:
+ # Allow for manual run of security workflows
+ workflow_dispatch:
+ # Scan changed files in PRs (diff-aware scanning):
+ pull_request: {}
+jobs:
+ running-3rd-party-pr-security-checks:
+ uses: verkada/securitybots/.github/workflows/3rd-party-pr-checks.yml@main
+ secrets: inherit
From 05e3ad61a1c9a5039188d406dc1cfe1a7a36d287 Mon Sep 17 00:00:00 2001
From: Nick Vines
Date: Fri, 13 Jun 2025 10:14:55 -0700
Subject: [PATCH 69/72] Workflow Updates - Runners, Only targets we use, limit
python versions, justfile, release on PRs
---
.github/workflows/linux.yml | 2 +-
.github/workflows/windows.yml | 4 +-
Justfile | 6 +-
ci-targets.yaml | 352 ----------------------------------
src/github.rs | 2 +-
src/release.rs | 77 --------
6 files changed, 6 insertions(+), 437 deletions(-)
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 68eef0e..d86dcf2 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -56,7 +56,7 @@ jobs:
path: target/release/pythonbuild
image:
- if: ${{ needs.generate-matrix.outputs.any_builds == 'true' }}
+ if: ${{ needs.generate-matrix.outputs.pythonbuild_changed == 'true' || needs.generate-matrix.outputs.any_builds == 'true' || github.ref == 'refs/heads/main' }}
needs:
- generate-matrix
strategy:
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 94bdc04..30f5878 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -1,9 +1,7 @@
name: windows
on:
- push:
- branches: [main]
- pull_request:
+ workflow_dispatch: # Only run manually
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }}
diff --git a/Justfile b/Justfile
index c9b8167..1118075 100644
--- a/Justfile
+++ b/Justfile
@@ -28,15 +28,15 @@ cat-python-json archive:
# Download release artifacts from GitHub Actions
release-download-distributions token commit:
mkdir -p dist
- cargo run --release -- fetch-release-distributions --token {{token}} --commit {{commit}} --dest dist
+ cargo run --release -- fetch-release-distributions --org verkada --token {{token}} --commit {{commit}} --dest dist
# Upload release artifacts to a GitHub release.
release-upload-distributions token datetime tag:
- cargo run --release -- upload-release-distributions --token {{token}} --datetime {{datetime}} --tag {{tag}} --dist dist
+ cargo run --release -- upload-release-distributions --org verkada --token {{token}} --datetime {{datetime}} --tag {{tag}} --dist dist
# "Upload" release artifacts to a GitHub release in dry-run mode (skip upload).
release-upload-distributions-dry-run token datetime tag:
- cargo run --release -- upload-release-distributions --token {{token}} --datetime {{datetime}} --tag {{tag}} --dist dist -n
+ cargo run --release -- upload-release-distributions --org verkada --token {{token}} --datetime {{datetime}} --tag {{tag}} --dist dist -n
# Promote a tag to "latest" by pushing to the `latest-release` branch.
release-set-latest-release tag:
diff --git a/ci-targets.yaml b/ci-targets.yaml
index 0662bbe..417333e 100644
--- a/ci-targets.yaml
+++ b/ci-targets.yaml
@@ -4,7 +4,6 @@ darwin:
aarch64-apple-darwin:
arch: aarch64
python_versions:
- - "3.9"
- "3.10"
- "3.11"
- "3.12"
@@ -22,7 +21,6 @@ darwin:
x86_64-apple-darwin:
arch: x86_64
python_versions:
- - "3.9"
- "3.10"
- "3.11"
- "3.12"
@@ -42,110 +40,6 @@ linux:
arch: aarch64
libc: gnu
python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug
- - pgo+lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+pgo+lto
- minimum-python-version: "3.13"
-
- armv7-unknown-linux-gnueabi:
- arch: armv7
- libc: gnu
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug
- - noopt
- - lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+noopt
- - freethreaded+lto
- minimum-python-version: "3.13"
-
- armv7-unknown-linux-gnueabihf:
- arch: armv7
- libc: gnu
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug
- - noopt
- - lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+noopt
- - freethreaded+lto
- minimum-python-version: "3.13"
-
- s390x-unknown-linux-gnu:
- arch: s390x
- libc: gnu
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug
- - noopt
- - lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+noopt
- - freethreaded+lto
- minimum-python-version: "3.13"
-
- ppc64le-unknown-linux-gnu:
- arch: ppc64le
- libc: gnu
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug
- - noopt
- - lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+noopt
- - freethreaded+lto
- minimum-python-version: "3.13"
-
- riscv64-unknown-linux-gnu:
- arch: riscv64
- libc: gnu
- python_versions:
- - "3.9"
- "3.10"
- "3.11"
- "3.12"
@@ -166,49 +60,6 @@ linux:
arch: x86_64
libc: gnu
python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug
- - pgo+lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+pgo+lto
- minimum-python-version: "3.13"
- run: true
-
- x86_64_v2-unknown-linux-gnu:
- arch: x86_64
- arch_variant: v2
- libc: gnu
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug
- - pgo+lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+pgo+lto
- minimum-python-version: "3.13"
- run: true
-
- x86_64_v3-unknown-linux-gnu:
- arch: x86_64
- arch_variant: v3
- libc: gnu
- python_versions:
- - "3.9"
- "3.10"
- "3.11"
- "3.12"
@@ -223,206 +74,3 @@ linux:
- freethreaded+pgo+lto
minimum-python-version: "3.13"
run: true
-
- x86_64_v4-unknown-linux-gnu:
- arch: x86_64
- arch_variant: v4
- libc: gnu
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug
- - pgo+lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+pgo+lto
- minimum-python-version: "3.13"
- run: true
-
- x86_64-unknown-linux-musl:
- arch: x86_64
- libc: musl
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug+static
- - noopt+static
- - lto+static
- - debug
- - noopt
- - lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+noopt
- - freethreaded+lto
- minimum-python-version: "3.13"
- run: true
-
- x86_64_v2-unknown-linux-musl:
- arch: x86_64
- arch_variant: v2
- libc: musl
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug+static
- - noopt+static
- - lto+static
- - debug
- - noopt
- - lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+noopt
- - freethreaded+lto
- minimum-python-version: "3.13"
- run: true
-
- x86_64_v3-unknown-linux-musl:
- arch: x86_64
- arch_variant: v3
- libc: musl
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug+static
- - noopt+static
- - lto+static
- - debug
- - noopt
- - lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+noopt
- - freethreaded+lto
- minimum-python-version: "3.13"
- run: true
-
- x86_64_v4-unknown-linux-musl:
- arch: x86_64
- arch_variant: v4
- libc: musl
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - debug+static
- - noopt+static
- - lto+static
- - debug
- - noopt
- - lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+noopt
- - freethreaded+lto
- minimum-python-version: "3.13"
- run: true
-
- aarch64-unknown-linux-musl:
- arch: aarch64
- libc: musl
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- # TODO: Static support is current blocked by some compiler-rt linking issues
- # - debug+static
- # - noopt+static
- # - lto+static
- - debug
- - noopt
- - lto
- build_options_conditional:
- - options:
- - freethreaded+debug
- - freethreaded+noopt
- - freethreaded+lto
- minimum-python-version: "3.13"
- run: true
-
-windows:
- i686-pc-windows-msvc:
- arch: x86
- vcvars: vcvars32.bat
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - pgo
- build_options_conditional:
- - options:
- - freethreaded+pgo
- minimum-python-version: "3.13"
-
- x86_64-pc-windows-msvc:
- arch: x86_64
- vcvars: vcvars64.bat
- python_versions:
- - "3.9"
- - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - pgo
- build_options_conditional:
- - options:
- - freethreaded+pgo
- minimum-python-version: "3.13"
-
- aarch64-pc-windows-msvc:
- arch: aarch64
- vcvars: vcvarsamd64_arm64.bat
- python_versions:
- # On 3.9 / 3.10, `_tkinter` is failing to be included in the build
- # - "3.9"
- # - "3.10"
- - "3.11"
- - "3.12"
- - "3.13"
- - "3.14"
- build_options:
- - pgo
- build_options_conditional:
- - options:
- - freethreaded+pgo
- minimum-python-version: "3.13"
diff --git a/src/github.rs b/src/github.rs
index 5db2247..a90b961 100644
--- a/src/github.rs
+++ b/src/github.rs
@@ -195,7 +195,6 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<()
wf.path.as_str(),
".github/workflows/macos.yml"
| ".github/workflows/linux.yml"
- | ".github/workflows/windows.yml"
) {
workflow_names.insert(wf.id, wf.name);
@@ -226,6 +225,7 @@ pub async fn command_fetch_release_distributions(args: &ArgMatches) -> Result<()
workflows
.list_runs(format!("{workflow_id}"))
.event("push")
+ .event("pull_request")
.status("success")
.send()
.await?
diff --git a/src/release.rs b/src/release.rs
index 4c123f6..564d544 100644
--- a/src/release.rs
+++ b/src/release.rs
@@ -145,19 +145,6 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy::
// Linux.
let linux_suffixes_pgo = vec!["debug", "pgo+lto"];
let linux_suffixes_nopgo = vec!["debug", "lto", "noopt"];
- let linux_suffixes_musl = vec![
- "debug",
- "lto",
- "noopt",
- "debug+static",
- "lto+static",
- "noopt+static",
- ];
- let linux_suffixes_musl_freethreaded = vec![
- "freethreaded+debug",
- "freethreaded+lto",
- "freethreaded+noopt",
- ];
let linux_suffixes_pgo_freethreaded = vec!["freethreaded+debug", "freethreaded+pgo+lto"];
let linux_suffixes_nopgo_freethreaded = vec![
"freethreaded+debug",
@@ -178,70 +165,6 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy::
},
);
- h.insert(
- "ppc64le-unknown-linux-gnu",
- TripleRelease {
- suffixes: linux_suffixes_nopgo.clone(),
- install_only_suffix: "lto",
- python_version_requirement: Some(VersionSpecifier::from_str(">=3.9").unwrap()),
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_nopgo_freethreaded.clone(),
- }],
- },
- );
-
- h.insert(
- "riscv64-unknown-linux-gnu",
- TripleRelease {
- suffixes: linux_suffixes_nopgo.clone(),
- install_only_suffix: "lto",
- python_version_requirement: Some(VersionSpecifier::from_str(">=3.9").unwrap()),
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_nopgo_freethreaded.clone(),
- }],
- },
- );
-
- h.insert(
- "s390x-unknown-linux-gnu",
- TripleRelease {
- suffixes: linux_suffixes_nopgo.clone(),
- install_only_suffix: "lto",
- python_version_requirement: Some(VersionSpecifier::from_str(">=3.9").unwrap()),
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_nopgo_freethreaded.clone(),
- }],
- },
- );
-
- h.insert(
- "armv7-unknown-linux-gnueabi",
- TripleRelease {
- suffixes: linux_suffixes_nopgo.clone(),
- install_only_suffix: "lto",
- python_version_requirement: Some(VersionSpecifier::from_str(">=3.9").unwrap()),
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_nopgo_freethreaded.clone(),
- }],
- },
- );
-
- h.insert(
- "armv7-unknown-linux-gnueabihf",
- TripleRelease {
- suffixes: linux_suffixes_nopgo.clone(),
- install_only_suffix: "lto",
- python_version_requirement: Some(VersionSpecifier::from_str(">=3.9").unwrap()),
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_nopgo_freethreaded.clone(),
- }],
- },
- );
h.insert(
"x86_64-unknown-linux-gnu",
From d7e049c34f740275aa5e86869a8e9b0d4f7ec6e8 Mon Sep 17 00:00:00 2001
From: Nick Vines
Date: Fri, 13 Jun 2025 10:15:05 -0700
Subject: [PATCH 70/72] Enable FIPS
---
cpython-unix/build-cpython.sh | 9 ++++++++-
cpython-unix/build-openssl-3.0.sh | 20 +++++++++++++++++---
src/validation.rs | 6 ++++++
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh
index d21533a..cb0cbce 100755
--- a/cpython-unix/build-cpython.sh
+++ b/cpython-unix/build-cpython.sh
@@ -44,7 +44,7 @@ sed "${sed_args[@]}" "s|/tools/host|${TOOLS_PATH}/host|g" ${TOOLS_PATH}/host/sha
# We force linking of external static libraries by removing the shared
# libraries. This is hacky. But we're building in a temporary container
# and it gets the job done.
-find ${TOOLS_PATH}/deps -name '*.so*' -a \! \( -name 'libtcl*.so*' -or -name 'libtk*.so*' \) -exec rm {} \;
+find ${TOOLS_PATH}/deps -name '*.so*' ! -name 'libtcl*.so*' ! -name 'libtk*.so*' ! -name 'fips.so' -exec rm {} \;
tar -xf Python-${PYTHON_VERSION}.tar.xz
@@ -1278,6 +1278,13 @@ if [ -d "${TOOLS_PATH}/deps/usr/share/terminfo" ]; then
cp -av ${TOOLS_PATH}/deps/usr/share/terminfo ${ROOT}/out/python/install/share/
fi
+# Copy files required to enable FIPS if enabled.
+if [ -f ${TOOLS_PATH}/deps/fipsmodule.cnf ]; then
+ mkdir -p ${ROOT}/out/python/install/share/ssl
+ cp -rv ${TOOLS_PATH}/deps/lib/ossl-modules ${ROOT}/out/python/install/share/ssl
+ cp -av ${TOOLS_PATH}/deps/fipsmodule.cnf ${ROOT}/out/python/install/share/ssl
+fi
+
# config.c defines _PyImport_Inittab and extern references to modules, which
# downstream consumers may want to strip. We bundle config.c and config.c.in so
# a custom one can be produced downstream.
diff --git a/cpython-unix/build-openssl-3.0.sh b/cpython-unix/build-openssl-3.0.sh
index 1d1f913..74526de 100755
--- a/cpython-unix/build-openssl-3.0.sh
+++ b/cpython-unix/build-openssl-3.0.sh
@@ -16,18 +16,23 @@ pushd openssl-${OPENSSL_3_0_VERSION}
# Otherwise it gets set to /tools/deps/ssl by default.
case "${TARGET_TRIPLE}" in
*apple*)
- EXTRA_FLAGS="--openssldir=/private/etc/ssl"
+ OPENSSL_DIR=/private/etc/ssl
;;
*)
- EXTRA_FLAGS="--openssldir=/etc/ssl"
+ OPENSSL_DIR=/etc/ssl
;;
esac
+EXTRA_FLAGS="--openssldir=${OPENSSL_DIR}"
+EXTRA_INSTALL_FLAGS=""
# musl is missing support for various primitives.
# TODO disable secure memory is a bit scary. We should look into a proper
# workaround.
if [ "${CC}" = "musl-clang" ]; then
EXTRA_FLAGS="${EXTRA_FLAGS} no-async -DOPENSSL_NO_ASYNC -D__STDC_NO_ATOMICS__=1 no-engine -DOPENSSL_NO_SECURE_MEMORY"
+else
+ EXTRA_INSTALL_FLAGS="install_fips"
+ EXTRA_FLAGS="${EXTRA_FLAGS} enable-fips"
fi
# The -arch cflags confuse Configure. And OpenSSL adds them anyway.
@@ -35,6 +40,10 @@ fi
EXTRA_TARGET_CFLAGS=${EXTRA_TARGET_CFLAGS/\-arch arm64/}
EXTRA_TARGET_CFLAGS=${EXTRA_TARGET_CFLAGS/\-arch x86_64/}
+# With -fvisibility=hidden, OSSL_provider_init symbol is not exported in fips module preventing it from loaded
+# OSSL_provider_init is supposed to be `extern` so it should not happen but I can't find a more targeted solution
+# at the moment.
+EXTRA_TARGET_CFLAGS=${EXTRA_TARGET_CFLAGS//-fvisibility=hidden/}
EXTRA_FLAGS="${EXTRA_FLAGS} ${EXTRA_TARGET_CFLAGS}"
/usr/bin/perl ./Configure \
@@ -47,4 +56,9 @@ EXTRA_FLAGS="${EXTRA_FLAGS} ${EXTRA_TARGET_CFLAGS}"
${EXTRA_FLAGS}
make -j ${NUM_CPUS}
-make -j ${NUM_CPUS} install_sw install_ssldirs DESTDIR=${ROOT}/out
+make -j ${NUM_CPUS} install_sw install_ssldirs ${EXTRA_INSTALL_FLAGS} DESTDIR=${ROOT}/out
+
+if [ -f ${ROOT}/out${OPENSSL_DIR}/fipsmodule.cnf ]; then
+ # install_fips does not use DESTDIR. we need to copy it so it gets added to the archive.
+ cp ${ROOT}/out${OPENSSL_DIR}/fipsmodule.cnf ${ROOT}/out/tools/deps/fipsmodule.cnf
+fi
diff --git a/src/validation.rs b/src/validation.rs
index 33e61e2..8a06bf8 100644
--- a/src/validation.rs
+++ b/src/validation.rs
@@ -1899,6 +1899,12 @@ fn validate_distribution(
let mut entry = entry.map_err(|e| anyhow!("failed to iterate over archive: {}", e))?;
let path = entry.path()?.to_path_buf();
+ if let Some(file_name) = path.file_name() {
+ if file_name == "fips.dylib" || file_name == "fips.so" {
+ continue
+ }
+ }
+
seen_paths.insert(path.clone());
if let Some(link_name) = entry.link_name()? {
From ce563b34476ce487ca956fd767002c08e9b6b57f Mon Sep 17 00:00:00 2001
From: nickvines
Date: Thu, 4 Sep 2025 14:21:31 -0700
Subject: [PATCH 71/72] Apply workflow and release configuration updates
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Remove Windows build targets from release configurations
- Remove unused Linux musl and versioned GNU targets
- Update release workflow to use ubuntu-latest runner
- Simplify build matrix to focus on essential targets only
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude
---
.github/workflows/release.yml | 2 +-
src/release.rs | 139 ----------------------------------
2 files changed, 1 insertion(+), 140 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index c3b3225..343ac8a 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -25,7 +25,7 @@ jobs:
name: Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- runs-on: depot-ubuntu-24.04-8
+ runs-on: ubuntu-latest
permissions:
contents: write
diff --git a/src/release.rs b/src/release.rs
index 564d544..d427c3b 100644
--- a/src/release.rs
+++ b/src/release.rs
@@ -104,53 +104,10 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy::
},
);
- // Windows.
- h.insert(
- "i686-pc-windows-msvc",
- TripleRelease {
- suffixes: vec!["pgo"],
- install_only_suffix: "pgo",
- python_version_requirement: None,
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: vec!["freethreaded+pgo"],
- }],
- },
- );
- h.insert(
- "x86_64-pc-windows-msvc",
- TripleRelease {
- suffixes: vec!["pgo"],
- install_only_suffix: "pgo",
- python_version_requirement: None,
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: vec!["freethreaded+pgo"],
- }],
- },
- );
- h.insert(
- "aarch64-pc-windows-msvc",
- TripleRelease {
- suffixes: vec!["pgo"],
- install_only_suffix: "pgo",
- python_version_requirement: Some(VersionSpecifier::from_str(">=3.11").unwrap()),
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: vec!["freethreaded+pgo"],
- }],
- },
- );
// Linux.
let linux_suffixes_pgo = vec!["debug", "pgo+lto"];
- let linux_suffixes_nopgo = vec!["debug", "lto", "noopt"];
let linux_suffixes_pgo_freethreaded = vec!["freethreaded+debug", "freethreaded+pgo+lto"];
- let linux_suffixes_nopgo_freethreaded = vec![
- "freethreaded+debug",
- "freethreaded+lto",
- "freethreaded+noopt",
- ];
h.insert(
"aarch64-unknown-linux-gnu",
@@ -178,102 +135,6 @@ pub static RELEASE_TRIPLES: Lazy> = Lazy::
}],
},
);
- h.insert(
- "x86_64_v2-unknown-linux-gnu",
- TripleRelease {
- suffixes: linux_suffixes_pgo.clone(),
- install_only_suffix: "pgo+lto",
- python_version_requirement: Some(VersionSpecifier::from_str(">=3.9").unwrap()),
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_pgo_freethreaded.clone(),
- }],
- },
- );
- h.insert(
- "x86_64_v3-unknown-linux-gnu",
- TripleRelease {
- suffixes: linux_suffixes_pgo.clone(),
- install_only_suffix: "pgo+lto",
- python_version_requirement: Some(VersionSpecifier::from_str(">=3.9").unwrap()),
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_pgo_freethreaded.clone(),
- }],
- },
- );
- h.insert(
- "x86_64_v4-unknown-linux-gnu",
- TripleRelease {
- suffixes: linux_suffixes_pgo.clone(),
- install_only_suffix: "pgo+lto",
- python_version_requirement: Some(VersionSpecifier::from_str(">=3.9").unwrap()),
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_pgo_freethreaded.clone(),
- }],
- },
- );
- h.insert(
- "x86_64-unknown-linux-musl",
- TripleRelease {
- suffixes: linux_suffixes_musl.clone(),
- install_only_suffix: "lto",
- python_version_requirement: None,
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_musl_freethreaded.clone(),
- }],
- },
- );
- h.insert(
- "x86_64_v2-unknown-linux-musl",
- TripleRelease {
- suffixes: linux_suffixes_musl.clone(),
- install_only_suffix: "lto",
- python_version_requirement: None,
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_musl_freethreaded.clone(),
- }],
- },
- );
- h.insert(
- "x86_64_v3-unknown-linux-musl",
- TripleRelease {
- suffixes: linux_suffixes_musl.clone(),
- install_only_suffix: "lto",
- python_version_requirement: None,
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_musl_freethreaded.clone(),
- }],
- },
- );
- h.insert(
- "x86_64_v4-unknown-linux-musl",
- TripleRelease {
- suffixes: linux_suffixes_musl.clone(),
- install_only_suffix: "lto",
- python_version_requirement: None,
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_musl_freethreaded.clone(),
- }],
- },
- );
- h.insert(
- "aarch64-unknown-linux-musl",
- TripleRelease {
- suffixes: vec!["debug", "lto", "noopt"],
- install_only_suffix: "lto",
- python_version_requirement: None,
- conditional_suffixes: vec![ConditionalSuffixes {
- python_version_requirement: VersionSpecifier::from_str(">=3.13").unwrap(),
- suffixes: linux_suffixes_musl_freethreaded.clone(),
- }],
- },
- );
h
});
From dcd76879ebb64e5c440bd4f57a2d8b0b195aa12b Mon Sep 17 00:00:00 2001
From: nickvines
Date: Thu, 4 Sep 2025 14:25:04 -0700
Subject: [PATCH 72/72] Fix stalled workflows by updating CI runners
configuration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Replace depot runners with standard GitHub runners
- Add support for aarch64 Linux builds with ubuntu-latest-aarch64
- Update all runners to use free GitHub-hosted runners
- Remove references to paid depot infrastructure
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude
---
ci-runners.yaml | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/ci-runners.yaml b/ci-runners.yaml
index dae6aab..6eff628 100644
--- a/ci-runners.yaml
+++ b/ci-runners.yaml
@@ -1,22 +1,22 @@
# Describes the runners that the CI system can use
-depot-ubuntu-22.04:
+ubuntu-latest:
arch: x86_64
platform: linux
- free: false
+ free: true
-depot-ubuntu-22.04-arm:
- arch: aarch64
+ubuntu-24.04:
+ arch: x86_64
platform: linux
- free: false
+ free: true
-depot-macos-latest:
+ubuntu-22.04:
arch: x86_64
- platform: darwin
- free: false
+ platform: linux
+ free: true
-ubuntu-latest:
- arch: x86_64
+ubuntu-latest-aarch64:
+ arch: aarch64
platform: linux
free: true
@@ -25,22 +25,22 @@ macos-latest:
platform: darwin
free: true
-depot-windows-2022-8:
- arch: x86_64
- platform: windows
- free: false
+macos-14:
+ arch: aarch64
+ platform: darwin
+ free: true
-windows-latest-large:
+macos-13:
arch: x86_64
- platform: windows
- free: false
+ platform: darwin
+ free: true
windows-latest:
arch: x86_64
platform: windows
free: true
-windows-11-arm:
- arch: aarch64
+windows-2022:
+ arch: x86_64
platform: windows
- free: false
+ free: true