diff --git a/ci/build-wheel.sh b/ci/build-wheel.sh index fbc57b47a..054a87fb7 100755 --- a/ci/build-wheel.sh +++ b/ci/build-wheel.sh @@ -6,8 +6,9 @@ PY_PLATFORM=$($PYTHON -c "import sysconfig; print(sysconfig.get_platform(), end= PY_VERSION=$($PYTHON -c "import sysconfig; print(sysconfig.get_python_version(), end='')") PY_VERSION_FULL=$($PYTHON -c "import sysconfig; print(sysconfig.get_config_var('py_version'), end='')") PY_VERSION_NODOT=$($PYTHON -c "import sysconfig; print(sysconfig.get_config_var('py_version_nodot'), end='')") +PY_ABI_THREAD=$($PYTHON -c "import sysconfig; print(sysconfig.get_config_var('abi_thread') or '', end='')") -PYTHON_TAG=cp$PY_VERSION_NODOT +PYTHON_TAG=cp$PY_VERSION_NODOT$PY_ABI_THREAD if [[ $PY_PLATFORM == linux* ]]; then PLATFORM_TAG=many$(echo $PY_PLATFORM | sed 's/\-/_/') PLATFORM_TAG_MASK=$(echo $PLATFORM_TAG | sed 's/_/*_/') diff --git a/cx_Freeze/executable.py b/cx_Freeze/executable.py index 1f00319ee..a4b49e5a4 100644 --- a/cx_Freeze/executable.py +++ b/cx_Freeze/executable.py @@ -74,12 +74,17 @@ def base(self) -> Path: @base.setter def base(self, name: str | Path | None) -> None: - # The default base is the legacy console, except for + # The default base is the legacy console, except for Python 3.13t and # Python 3.13 on macOS, that supports only the new console - if IS_MACOS and sys.version_info[:2] >= (3, 13): - name = name or "console" - else: + version = sys.version_info[:2] + if ( + version <= (3, 13) + and get_config_var("abi_thread") is None + and not (IS_MACOS and version == (3, 13)) + ): name = name or "console_legacy" + else: + name = name or "console" # silently ignore gui and service on non-windows systems if not (IS_WINDOWS or IS_MINGW) and name in ("gui", "service"): name = "console" diff --git a/pyproject.toml b/pyproject.toml index e32659e57..ea649751a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,7 +61,7 @@ dynamic = ["version"] [project.optional-dependencies] dev = [ - "bump-my-version==0.29.0", + "bump-my-version==0.29.0 ;python_version < '3.13'", "cibuildwheel==2.22.0", "pre-commit==4.0.1", # python_version >= 3.9 ] @@ -165,10 +165,12 @@ before-build = "uv pip install -r requirements.txt" build = "cp3*" build-frontend = "build[uv]" build-verbosity = 1 +enable = ["cpython-freethreading"] skip = [ "cp3{9,10,13}-musllinux_*", "cp3{9,10,13}-manylinux_ppc64le", "cp3{9,10}-macosx_{universal2,arm64}", + "cp313t-win*", ] [tool.cibuildwheel.linux] diff --git a/requirements-dev.txt b/requirements-dev.txt index e366973e1..48d4793ef 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,3 @@ -bump-my-version==0.29.0 +bump-my-version==0.29.0 ;python_version < '3.13' cibuildwheel==2.22.0 pre-commit==4.0.1 diff --git a/setup.py b/setup.py index aab1b7a5b..0f56ffda9 100644 --- a/setup.py +++ b/setup.py @@ -97,7 +97,8 @@ def build_extension(self, ext) -> None: library_dirs.append(get_config_var("LIBPL")) if not ENABLE_SHARED or IS_CONDA: library_dirs.append(get_config_var("LIBDIR")) - libraries.append(f"python{get_python_version()}") + abi_thread = get_config_var("abi_thread") or "" + libraries.append(f"python{get_python_version()}{abi_thread}") if get_config_var("LIBS"): extra_args.extend(get_config_var("LIBS").split()) if get_config_var("LIBM"): @@ -275,38 +276,48 @@ def get_extensions() -> list[Extension]: os.environ.get("CI", "") != "true" or os.environ.get("CIBUILDWHEEL", "0") != "1" ) + abi_thread = get_config_var("abi_thread") + version = sys.version_info[:2] extensions = [ Extension( "cx_Freeze.bases.console", ["source/bases/console.c", "source/bases/_common.c"], optional=optional, - ), - Extension( - "cx_Freeze.bases.console_legacy", - ["source/legacy/console.c"], - depends=["source/legacy/common.c"], - optional=optional - or (sys.version_info[:2] >= (3, 13) and IS_MACOS), - ), + ) ] - - if IS_MINGW or IS_WINDOWS: + if ( + version <= (3, 13) + and abi_thread is None + and not (IS_MACOS and version == (3, 13)) + ): extensions += [ Extension( - "cx_Freeze.bases.Win32GUI", - ["source/legacy/Win32GUI.c"], + "cx_Freeze.bases.console_legacy", + ["source/legacy/console.c"], depends=["source/legacy/common.c"], - libraries=["user32"], optional=optional, - ), - Extension( - "cx_Freeze.bases.Win32Service", - ["source/legacy/Win32Service.c"], - depends=["source/legacy/common.c"], - extra_link_args=["/DELAYLOAD:cx_Logging"], - libraries=["advapi32"], - optional=optional, - ), + ) + ] + if IS_MINGW or IS_WINDOWS: + if version <= (3, 13) and abi_thread is None: + extensions += [ + Extension( + "cx_Freeze.bases.Win32GUI", + ["source/legacy/Win32GUI.c"], + depends=["source/legacy/common.c"], + libraries=["user32"], + optional=optional, + ), + Extension( + "cx_Freeze.bases.Win32Service", + ["source/legacy/Win32Service.c"], + depends=["source/legacy/common.c"], + extra_link_args=["/DELAYLOAD:cx_Logging"], + libraries=["advapi32"], + optional=optional, + ), + ] + extensions += [ Extension( "cx_Freeze.bases.gui", ["source/bases/Win32GUI.c", "source/bases/_common.c"], diff --git a/tests/test_executables.py b/tests/test_executables.py index b9b5c2ad4..77fa452c1 100644 --- a/tests/test_executables.py +++ b/tests/test_executables.py @@ -5,6 +5,7 @@ import shutil import sys from pathlib import Path +from sysconfig import get_config_var import pytest from generate_samples import create_package, run_command @@ -241,14 +242,18 @@ def test_executables( ("icon.ico", "icon.icns", "icon.png", "icon.svg"), ), ] -if IS_MACOS and sys.version_info[:2] >= (3, 13): +if ( + sys.version_info[:2] <= (3, 13) + and get_config_var("abi_thread") is None + and not (IS_MACOS and sys.version_info[:2] == (3, 13)) +): TEST_VALID_PARAMETERS += [ - ("base", None, "console-"), + ("base", None, "console_legacy-"), + ("base", "console_legacy", "console_legacy-"), ] else: TEST_VALID_PARAMETERS += [ - ("base", None, "console_legacy-"), - ("base", "console_legacy", "console_legacy-"), + ("base", None, "console-"), ] if IS_WINDOWS or IS_MINGW: TEST_VALID_PARAMETERS += [