diff --git a/cpython-windows/build.py b/cpython-windows/build.py
index 9195e071..74fc2422 100644
--- a/cpython-windows/build.py
+++ b/cpython-windows/build.py
@@ -65,7 +65,10 @@
"_lzma": {
"ignore_additional_depends": {"$(OutDir)liblzma$(PyDebugExt).lib"},
},
- "_msi": {},
+ "_msi": {
+ # Removed in 3.13.
+ "ignore_missing": True,
+ },
"_overlapped": {},
"_multiprocessing": {},
"_socket": {},
@@ -352,6 +355,7 @@ def hack_props(
xz_version = DOWNLOADS["xz"]["version"]
zlib_version = DOWNLOADS["zlib"]["version"]
tcltk_commit = DOWNLOADS["tk-windows-bin"]["git_commit"]
+ mpdecimal_version = DOWNLOADS["mpdecimal"]["version"]
sqlite_path = td / ("sqlite-autoconf-%s" % sqlite_version)
bzip2_path = td / ("bzip2-%s" % bzip2_version)
@@ -359,6 +363,7 @@ def hack_props(
tcltk_path = td / ("cpython-bin-deps-%s" % tcltk_commit)
xz_path = td / ("xz-%s" % xz_version)
zlib_path = td / ("zlib-%s" % zlib_version)
+ mpdecimal_path = td / ("mpdecimal-%s" % mpdecimal_version)
openssl_root = td / "openssl" / arch
openssl_libs_path = openssl_root / "lib"
@@ -398,6 +403,9 @@ def hack_props(
elif b"%s\\" % zlib_path
+ elif b"%s\\" % mpdecimal_path
+
lines.append(line)
with python_props_path.open("wb") as fh:
@@ -1155,15 +1163,17 @@ def collect_python_build_artifacts(
"_ctypes_test",
"_testbuffer",
"_testcapi",
+ "_testclinic_limited",
"_testclinic",
"_testconsole",
"_testembed",
"_testimportmultiple",
"_testinternalcapi",
- "_testsinglephase",
+ "_testlimitedcapi",
"_testmultiphase",
- "xxlimited",
+ "_testsinglephase",
"xxlimited_35",
+ "xxlimited",
}
other_projects = {"pythoncore"}
@@ -1409,6 +1419,12 @@ def build_cpython(
setuptools_wheel = download_entry("setuptools", BUILD)
pip_wheel = download_entry("pip", BUILD)
+ # CPython 3.13+ no longer uses a bundled version by default
+ if meets_python_minimum_version(python_version, "3.13"):
+ mpdecimal_archive = download_entry("mpdecimal", BUILD)
+ else:
+ mpdecimal_archive = None
+
if arch == "amd64":
build_platform = "x64"
build_directory = "amd64"
@@ -1426,12 +1442,16 @@ def build_cpython(
for a in (
python_archive,
bzip2_archive,
+ mpdecimal_archive,
openssl_archive,
sqlite_archive,
tk_bin_archive,
xz_archive,
zlib_archive,
):
+ if a is None:
+ continue
+
log("extracting %s to %s" % (a, td))
fs.append(e.submit(extract_tar_to_directory, a, td))
@@ -1599,11 +1619,6 @@ def build_cpython(
if not meets_python_minimum_version(python_version, "3.12"):
args.append("--include-distutils")
- # CPython 3.13+ no longer uses a bundled libmpdec by default
- # TODO(zanieb): We should use the system libmpdec as we do for Unix builds
- if meets_python_minimum_version(python_version, "3.13"):
- args.append("--with-system-libmpdec=no")
-
args.extend(["--include-idle", "--include-stable", "--include-tcltk"])
exec_and_log(
diff --git a/src/validation.rs b/src/validation.rs
index af94f7c6..434c1a32 100644
--- a/src/validation.rs
+++ b/src/validation.rs
@@ -125,6 +125,7 @@ const PE_ALLOWED_LIBRARIES: &[&str] = &[
"python310.dll",
"python311.dll",
"python312.dll",
+ "python313.dll",
"sqlite3.dll",
"tcl86t.dll",
"tk86t.dll",
@@ -679,7 +680,13 @@ const GLOBAL_EXTENSIONS: &[&str] = &[
// We didn't build ctypes_test until 3.9.
// We didn't build some test extensions until 3.9.
-const GLOBAL_EXTENSIONS_PYTHON_3_8: &[&str] = &["audioop", "_sha256", "_sha512", "parser"];
+const GLOBAL_EXTENSIONS_PYTHON_3_8: &[&str] = &[
+ "audioop",
+ "_sha256",
+ "_sha512",
+ "parser",
+ "_xxsubinterpreters",
+];
const GLOBAL_EXTENSIONS_PYTHON_3_9: &[&str] = &[
"audioop",
@@ -727,9 +734,7 @@ const GLOBAL_EXTENSIONS_PYTHON_3_13: &[&str] = &[
"_interpqueues",
"_interpreters",
"_sha2",
- "_suggestions",
"_sysconfig",
- "_testexternalinspection",
"_tokenize",
"_typing",
"_zoneinfo",
@@ -759,16 +764,16 @@ const GLOBAL_EXTENSIONS_POSIX: &[&str] = &[
const GLOBAL_EXTENSIONS_LINUX_PRE_3_13: &[&str] = &["spwd"];
const GLOBAL_EXTENSIONS_WINDOWS: &[&str] = &[
- "_msi",
"_overlapped",
"_winapi",
- "_xxsubinterpreters",
"msvcrt",
"nt",
"winreg",
"winsound",
];
+const GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13: &[&str] = &["_msi"];
+
/// Extension modules not present in Windows static builds.
const GLOBAL_EXTENSIONS_WINDOWS_NO_STATIC: &[&str] = &["_testinternalcapi", "_tkinter"];
@@ -1494,6 +1499,10 @@ fn validate_extension_modules(
if is_windows {
wanted.extend(GLOBAL_EXTENSIONS_WINDOWS);
+ if matches!(python_major_minor, "3.8" | "3.9" | "3.10" | "3.11" | "3.12") {
+ wanted.extend(GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13);
+ }
+
if static_crt {
for x in GLOBAL_EXTENSIONS_WINDOWS_NO_STATIC {
wanted.remove(*x);
@@ -1949,9 +1958,10 @@ fn validate_distribution(
// Static distributions never export symbols.
let wanted = if is_static {
false
- // For some strange reason _PyWarnings_Init is exported as part of the ABI.
+ // For some strange reason _PyWarnings_Init is exported as part of the ABI before
+ // Python 3.13.
} else if name == "_warnings" {
- true
+ matches!(python_major_minor, "3.8" | "3.9" | "3.10" | "3.11" | "3.12")
// Windows dynamic doesn't export extension module init functions.
} else if triple.contains("-windows-") {
false