From 31b7eab6ee6264912f61abde5e9f5a515c777eb6 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 28 Mar 2025 00:19:33 +0800 Subject: [PATCH 01/43] Add `ABIFLAGS` to `sysconfig.get_config_vars()` on Windows --- Lib/sysconfig/__init__.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index 18e6b8d25e5b56..42d9ffb919747b 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -414,6 +414,13 @@ def _init_non_posix(vars): vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) vars['TZPATH'] = '' + abiflags = vars['abi_thread'] + if vars['EXT_SUFFIX'].endswith('_d.'): + abiflags += 'd' + # Do not touch lower-cased `abiflags` here. + # sys.abiflags is absent on Windows. So vars['abiflags'] should be empty. + vars['ABIFLAGS'] = abiflags + # # public APIs # @@ -541,6 +548,9 @@ def _init_config_vars(): except AttributeError: _CONFIG_VARS['py_version_nodot_plat'] = '' + # e.g., 't' for free-threaded or '' for default build + _CONFIG_VARS['abi_thread'] = 't' if _CONFIG_VARS.get('Py_GIL_DISABLED') else '' + if os.name == 'nt': _init_non_posix(_CONFIG_VARS) _CONFIG_VARS['VPATH'] = sys._vpath @@ -550,9 +560,6 @@ def _init_config_vars(): # the init-function. _CONFIG_VARS['userbase'] = _getuserbase() - # e.g., 't' for free-threaded or '' for default build - _CONFIG_VARS['abi_thread'] = 't' if _CONFIG_VARS.get('Py_GIL_DISABLED') else '' - # Always convert srcdir to an absolute path srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) if os.name == 'posix': From dc458977134f42475c646373e3115e7701a566a8 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 16:23:01 +0000 Subject: [PATCH 02/43] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Windows/2025-03-27-16-22-58.gh-issue-127405.aASs2Z.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Windows/2025-03-27-16-22-58.gh-issue-127405.aASs2Z.rst diff --git a/Misc/NEWS.d/next/Windows/2025-03-27-16-22-58.gh-issue-127405.aASs2Z.rst b/Misc/NEWS.d/next/Windows/2025-03-27-16-22-58.gh-issue-127405.aASs2Z.rst new file mode 100644 index 00000000000000..a6d5985ff4c7b8 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2025-03-27-16-22-58.gh-issue-127405.aASs2Z.rst @@ -0,0 +1 @@ +Add ``ABIFLAGS`` to :func:`sysconfig.get_config_vars` on Windows. Patch by Xuehai Pan. From 9a4586a617cc738e7cf1f75ebd7a8451509b710d Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 28 Mar 2025 02:07:46 +0800 Subject: [PATCH 03/43] Add tests --- Lib/test/test_sysconfig.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 3738914cf17de8..e08b90611b385f 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -592,6 +592,10 @@ def test_osx_ext_suffix(self): suffix = sysconfig.get_config_var('EXT_SUFFIX') self.assertTrue(suffix.endswith('-darwin.so'), suffix) + def test_always_set_ABIFLAGS(self): + self.assertIn('ABIFLAGS', sysconfig.get_config_vars()) + self.assertIsInstance(sysconfig.get_config_var('ABIFLAGS'), str) + @requires_subprocess() def test_makefile_overwrites_config_vars(self): script = textwrap.dedent(""" From 76c85bbee5fb42b3936fc683f4709747a0737b33 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 28 Mar 2025 16:01:45 +0800 Subject: [PATCH 04/43] Move `ABIFLAGS` definition to C code --- Lib/sysconfig/__init__.py | 12 +++++------- Misc/ACKS | 1 + Modules/_sysconfig.c | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index 42d9ffb919747b..97db2f3cbb2f5a 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -401,7 +401,11 @@ def _init_non_posix(vars): vars['BINLIBDEST'] = get_path('platstdlib') vars['INCLUDEPY'] = get_path('include') - # Add EXT_SUFFIX, SOABI, and Py_GIL_DISABLED + # Add EXT_SUFFIX, SOABI, ABIFLAGS, and Py_GIL_DISABLED (defined in Modules/_sysconfig.c) + # NOTE: ABIFLAGS is only an emulated value. It is not present during build + # on Windows. sys.abiflags is absent on Windows and `vars['abiflags'] + # is already widely used to calculate paths. vars['abiflags'] should + # remain empty string. vars.update(_sysconfig.config_vars()) vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs')) @@ -414,12 +418,6 @@ def _init_non_posix(vars): vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) vars['TZPATH'] = '' - abiflags = vars['abi_thread'] - if vars['EXT_SUFFIX'].endswith('_d.'): - abiflags += 'd' - # Do not touch lower-cased `abiflags` here. - # sys.abiflags is absent on Windows. So vars['abiflags'] should be empty. - vars['ABIFLAGS'] = abiflags # # public APIs diff --git a/Misc/ACKS b/Misc/ACKS index b0b4ea0db44b64..e7a7bac5ca151e 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1402,6 +1402,7 @@ Todd R. Palmer Juan David Ibáñez Palomar Nicola Palumbo Jan Palus +Xuehai Pan Yongzhi Pan Martin Panter Mathias Panzenböck diff --git a/Modules/_sysconfig.c b/Modules/_sysconfig.c index c50c5cfabc2f1f..ebf2d24075abe4 100644 --- a/Modules/_sysconfig.c +++ b/Modules/_sysconfig.c @@ -55,6 +55,30 @@ _sysconfig_config_vars_impl(PyObject *module) Py_DECREF(config); return NULL; } + + // On Unix, the `ABIFLAGS` key is defined via a different logic. +# ifdef Py_GIL_DISABLED +# define _SYSCONFIG_ABI_THREAD "t" +# else +# define _SYSCONFIG_ABI_THREAD "" +# endif +# ifdef _DEBUG +# define _SYSCONFIG_ABI_DEBUG "d" +# else +# define _SYSCONFIG_ABI_DEBUG "" +# endif +# define _SYSCONFIG_ABIFLAGS (_SYSCONFIG_ABI_THREAD _SYSCONFIG_ABI_DEBUG) + + // Emulate `sys.abiflags` value on Unix for Windows. ABIFLAGS here is only + // an emulated value. It is not present during build on Windows. + if (add_string_value(config, "ABIFLAGS", SYSCONFIG_ABIFLAGS) < 0) { + Py_DECREF(config); + return NULL; + } + +# undef _SYSCONFIG_ABI_THREAD +# undef _SYSCONFIG_ABI_DEBUG +# undef _SYSCONFIG_ABIFLAGS #endif #ifdef Py_GIL_DISABLED From b98419b410d2a7f2a7a93f4351657f074e88a5d1 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 28 Mar 2025 16:24:14 +0800 Subject: [PATCH 05/43] Revert now unrelated changes --- Lib/sysconfig/__init__.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index 97db2f3cbb2f5a..479883d117c39f 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -401,12 +401,12 @@ def _init_non_posix(vars): vars['BINLIBDEST'] = get_path('platstdlib') vars['INCLUDEPY'] = get_path('include') - # Add EXT_SUFFIX, SOABI, ABIFLAGS, and Py_GIL_DISABLED (defined in Modules/_sysconfig.c) + # Add EXT_SUFFIX, SOABI, ABIFLAGS, and Py_GIL_DISABLED # NOTE: ABIFLAGS is only an emulated value. It is not present during build # on Windows. sys.abiflags is absent on Windows and `vars['abiflags'] # is already widely used to calculate paths. vars['abiflags'] should # remain empty string. - vars.update(_sysconfig.config_vars()) + vars.update(_sysconfig.config_vars()) # defined in Modules/_sysconfig.c vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs')) if hasattr(sys, 'dllhandle'): @@ -418,7 +418,6 @@ def _init_non_posix(vars): vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) vars['TZPATH'] = '' - # # public APIs # @@ -546,9 +545,6 @@ def _init_config_vars(): except AttributeError: _CONFIG_VARS['py_version_nodot_plat'] = '' - # e.g., 't' for free-threaded or '' for default build - _CONFIG_VARS['abi_thread'] = 't' if _CONFIG_VARS.get('Py_GIL_DISABLED') else '' - if os.name == 'nt': _init_non_posix(_CONFIG_VARS) _CONFIG_VARS['VPATH'] = sys._vpath @@ -558,6 +554,9 @@ def _init_config_vars(): # the init-function. _CONFIG_VARS['userbase'] = _getuserbase() + # e.g., 't' for free-threaded or '' for default build + _CONFIG_VARS['abi_thread'] = 't' if _CONFIG_VARS.get('Py_GIL_DISABLED') else '' + # Always convert srcdir to an absolute path srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) if os.name == 'posix': From 4729f76217cc78a8ebd8c5364a10da53f22b984c Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 28 Mar 2025 16:30:22 +0800 Subject: [PATCH 06/43] Fix variable name --- Modules/_sysconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_sysconfig.c b/Modules/_sysconfig.c index ebf2d24075abe4..dd18bad08acfba 100644 --- a/Modules/_sysconfig.c +++ b/Modules/_sysconfig.c @@ -71,7 +71,7 @@ _sysconfig_config_vars_impl(PyObject *module) // Emulate `sys.abiflags` value on Unix for Windows. ABIFLAGS here is only // an emulated value. It is not present during build on Windows. - if (add_string_value(config, "ABIFLAGS", SYSCONFIG_ABIFLAGS) < 0) { + if (add_string_value(config, "ABIFLAGS", _SYSCONFIG_ABIFLAGS) < 0) { Py_DECREF(config); return NULL; } From 04cbb1c2a860137190a6bcf64e2d46ce5252b8fc Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Sat, 29 Mar 2025 00:59:39 +0800 Subject: [PATCH 07/43] Refactor string concatination --- Modules/_sysconfig.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/Modules/_sysconfig.c b/Modules/_sysconfig.c index dd18bad08acfba..7fc3e86cfb67f0 100644 --- a/Modules/_sysconfig.c +++ b/Modules/_sysconfig.c @@ -57,28 +57,21 @@ _sysconfig_config_vars_impl(PyObject *module) } // On Unix, the `ABIFLAGS` key is defined via a different logic. + // + // Emulate `sys.abiflags` value on Unix for Windows. ABIFLAGS here is only + // an emulated value. It is not present during build on Windows. + if (add_string_value(config, "ABIFLAGS", # ifdef Py_GIL_DISABLED -# define _SYSCONFIG_ABI_THREAD "t" -# else -# define _SYSCONFIG_ABI_THREAD "" + "t" # endif # ifdef _DEBUG -# define _SYSCONFIG_ABI_DEBUG "d" -# else -# define _SYSCONFIG_ABI_DEBUG "" + "d" # endif -# define _SYSCONFIG_ABIFLAGS (_SYSCONFIG_ABI_THREAD _SYSCONFIG_ABI_DEBUG) - - // Emulate `sys.abiflags` value on Unix for Windows. ABIFLAGS here is only - // an emulated value. It is not present during build on Windows. - if (add_string_value(config, "ABIFLAGS", _SYSCONFIG_ABIFLAGS) < 0) { + "") + < 0) { Py_DECREF(config); return NULL; } - -# undef _SYSCONFIG_ABI_THREAD -# undef _SYSCONFIG_ABI_DEBUG -# undef _SYSCONFIG_ABIFLAGS #endif #ifdef Py_GIL_DISABLED From a6045ea23b599eead4e0c22b89bcf70995111ddf Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Sat, 29 Mar 2025 02:33:26 +0800 Subject: [PATCH 08/43] Set `Py_DEBUG` flag in sysconfig --- Lib/sysconfig/__init__.py | 2 +- Modules/_sysconfig.c | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index 479883d117c39f..ca03c33af7bbfb 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -401,7 +401,7 @@ def _init_non_posix(vars): vars['BINLIBDEST'] = get_path('platstdlib') vars['INCLUDEPY'] = get_path('include') - # Add EXT_SUFFIX, SOABI, ABIFLAGS, and Py_GIL_DISABLED + # Add EXT_SUFFIX, SOABI, ABIFLAGS, Py_DEBUG, and Py_GIL_DISABLED # NOTE: ABIFLAGS is only an emulated value. It is not present during build # on Windows. sys.abiflags is absent on Windows and `vars['abiflags'] # is already widely used to calculate paths. vars['abiflags'] should diff --git a/Modules/_sysconfig.c b/Modules/_sysconfig.c index 7fc3e86cfb67f0..ccdce2bc9ac614 100644 --- a/Modules/_sysconfig.c +++ b/Modules/_sysconfig.c @@ -64,8 +64,15 @@ _sysconfig_config_vars_impl(PyObject *module) # ifdef Py_GIL_DISABLED "t" # endif -# ifdef _DEBUG +# ifdef Py_DEBUG +# ifndef _DEBUG +# error "_DEBUG not defined while Py_DEBUG is defined on Windows" +# endif "d" +# else +# ifdef _DEBUG +# error "_DEBUG defined while Py_DEBUG is not defined on Windows" +# endif # endif "") < 0) { @@ -84,6 +91,16 @@ _sysconfig_config_vars_impl(PyObject *module) return NULL; } +#ifdef Py_DEBUG + PyObject *py_debug = _PyLong_GetOne(); +#else + PyObject *py_debug = _PyLong_GetZero(); +#endif + if (PyDict_SetItemString(config, "Py_DEBUG", py_debug) < 0) { + Py_DECREF(config); + return NULL; + } + return config; } From 584e0b056677cae93a1531a8f46e203707fd5cc2 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Sat, 29 Mar 2025 02:35:15 +0800 Subject: [PATCH 09/43] Update comments from code review --- Lib/sysconfig/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index ca03c33af7bbfb..759b8da1337e0c 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -403,9 +403,9 @@ def _init_non_posix(vars): # Add EXT_SUFFIX, SOABI, ABIFLAGS, Py_DEBUG, and Py_GIL_DISABLED # NOTE: ABIFLAGS is only an emulated value. It is not present during build - # on Windows. sys.abiflags is absent on Windows and `vars['abiflags'] - # is already widely used to calculate paths. vars['abiflags'] should - # remain empty string. + # on Windows. sys.abiflags is absent on Windows and vars['abiflags'] + # is already widely used to calculate paths, so it should remain an + # empty string. vars.update(_sysconfig.config_vars()) # defined in Modules/_sysconfig.c vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs')) From 93257bec96a9c07945d4d05a1ea8535d87bc97a2 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Sat, 29 Mar 2025 02:54:06 +0800 Subject: [PATCH 10/43] Prefer `Py_DEBUG` over `_DEBUG` --- Include/internal/pycore_importdl.h | 2 +- Modules/_sysconfig.c | 7 ------- PC/launcher.c | 2 +- PC/pyconfig.h.in | 17 +++++++++-------- PC/python_uwp.cpp | 4 ++-- PC/python_ver_rc.h | 2 +- PCbuild/pyproject.props | 2 +- Python/dynload_win.c | 6 +++--- 8 files changed, 18 insertions(+), 24 deletions(-) diff --git a/Include/internal/pycore_importdl.h b/Include/internal/pycore_importdl.h index 525a16f6b97274..3ba9229cc21378 100644 --- a/Include/internal/pycore_importdl.h +++ b/Include/internal/pycore_importdl.h @@ -107,7 +107,7 @@ extern int _PyImport_RunModInitFunc( #include typedef FARPROC dl_funcptr; -#ifdef _DEBUG +#ifdef Py_DEBUG # define PYD_DEBUG_SUFFIX "_d" #else # define PYD_DEBUG_SUFFIX "" diff --git a/Modules/_sysconfig.c b/Modules/_sysconfig.c index ccdce2bc9ac614..728cb4b252f2e3 100644 --- a/Modules/_sysconfig.c +++ b/Modules/_sysconfig.c @@ -65,14 +65,7 @@ _sysconfig_config_vars_impl(PyObject *module) "t" # endif # ifdef Py_DEBUG -# ifndef _DEBUG -# error "_DEBUG not defined while Py_DEBUG is defined on Windows" -# endif "d" -# else -# ifdef _DEBUG -# error "_DEBUG defined while Py_DEBUG is not defined on Windows" -# endif # endif "") < 0) { diff --git a/PC/launcher.c b/PC/launcher.c index 47fafbc3bf6bad..40e6630b82e17a 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -140,7 +140,7 @@ static wchar_t * get_env(wchar_t * key) return buf; } -#if defined(_DEBUG) +#if defined(Py_DEBUG) /* Do not define EXECUTABLEPATH_VALUE in debug builds as it'll never point to the debug build. */ #if defined(_WINDOWS) diff --git a/PC/pyconfig.h.in b/PC/pyconfig.h.in index 9e70303868e5de..2fa73807c93bac 100644 --- a/PC/pyconfig.h.in +++ b/PC/pyconfig.h.in @@ -289,6 +289,11 @@ typedef int pid_t; # include #endif +// _DEBUG implies Py_DEBUG +#ifdef _DEBUG +# define Py_DEBUG +#endif + /* 64 bit ints are usually spelt __int64 unless compiler has overridden */ #ifndef PY_LONG_LONG # define PY_LONG_LONG __int64 @@ -319,21 +324,21 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ This is relevant when using build-system generator (e.g CMake) where the linking is explicitly handled */ # if defined(Py_GIL_DISABLED) -# if defined(_DEBUG) +# if defined(Py_DEBUG) # pragma comment(lib,"python314t_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3t.lib") # else # pragma comment(lib,"python314t.lib") -# endif /* _DEBUG */ +# endif /* Py_DEBUG */ # else /* Py_GIL_DISABLED */ -# if defined(_DEBUG) +# if defined(Py_DEBUG) # pragma comment(lib,"python314_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3.lib") # else # pragma comment(lib,"python314.lib") -# endif /* _DEBUG */ +# endif /* Py_DEBUG */ # endif /* Py_GIL_DISABLED */ # endif /* _MSC_VER && !Py_NO_LINK_LIB */ # endif /* Py_BUILD_CORE */ @@ -376,10 +381,6 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ # define ALIGNOF_MAX_ALIGN_T 8 #endif -#ifdef _DEBUG -# define Py_DEBUG -#endif - #ifdef MS_WIN32 diff --git a/PC/python_uwp.cpp b/PC/python_uwp.cpp index b9c408a580c999..8cdb8d722cdb9a 100644 --- a/PC/python_uwp.cpp +++ b/PC/python_uwp.cpp @@ -19,13 +19,13 @@ #include #ifdef PYTHONW -#ifdef _DEBUG +#ifdef Py_DEBUG const wchar_t *PROGNAME = L"pythonw_d.exe"; #else const wchar_t *PROGNAME = L"pythonw.exe"; #endif #else -#ifdef _DEBUG +#ifdef Py_DEBUG const wchar_t *PROGNAME = L"python_d.exe"; #else const wchar_t *PROGNAME = L"python.exe"; diff --git a/PC/python_ver_rc.h b/PC/python_ver_rc.h index ee867fe41224c3..bb98144cd03f15 100644 --- a/PC/python_ver_rc.h +++ b/PC/python_ver_rc.h @@ -10,7 +10,7 @@ #define MS_WINDOWS #include "modsupport.h" #include "patchlevel.h" -#ifdef _DEBUG +#ifdef Py_DEBUG # define PYTHON_DEBUG_EXT "_d" #else # define PYTHON_DEBUG_EXT diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index 4e414dc913b9d5..83a34cf18961df 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -42,7 +42,7 @@ <_DebugPreprocessorDefinition>NDEBUG; - <_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG; + <_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG;Py_DEBUG; <_PyStatsPreprocessorDefinition>PyStats; <_PyStatsPreprocessorDefinition Condition="$(PySTATS) != ''">Py_STATS; <_PlatformPreprocessorDefinition>_WIN32; diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 6324063401e51f..de9b0a77817a63 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -108,7 +108,7 @@ static char *GetPythonImport (HINSTANCE hModule) char *pch; /* Don't claim that python3.dll is a Python DLL. */ -#ifdef _DEBUG +#ifdef Py_DEBUG if (strcmp(import_name, "python3_d.dll") == 0) { #else if (strcmp(import_name, "python3.dll") == 0) { @@ -120,7 +120,7 @@ static char *GetPythonImport (HINSTANCE hModule) /* Ensure python prefix is followed only by numbers to the end of the basename */ pch = import_name + 6; -#ifdef _DEBUG +#ifdef Py_DEBUG while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') { #else while (*pch && *pch != '.') { @@ -300,7 +300,7 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, char buffer[256]; PyOS_snprintf(buffer, sizeof(buffer), -#ifdef _DEBUG +#ifdef Py_DEBUG "python%d%d_d.dll", #else "python%d%d.dll", From 30c7b56442cb29aa2c02e7beab96e25e3c69345a Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Sat, 29 Mar 2025 02:56:25 +0800 Subject: [PATCH 11/43] Add tests --- Lib/test/test_sysconfig.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index e08b90611b385f..f951af75b894ae 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -596,6 +596,20 @@ def test_always_set_ABIFLAGS(self): self.assertIn('ABIFLAGS', sysconfig.get_config_vars()) self.assertIsInstance(sysconfig.get_config_var('ABIFLAGS'), str) + def test_always_set_Py_DEBUG(self): + self.assertIn('Py_DEBUG', sysconfig.get_config_vars()) + self.assertIn(sysconfig.get_config_var('Py_DEBUG'), (0, 1)) + + def test_ABIFLAGS(self): + if sysconfig.get_config_var('Py_DEBUG'): + self.assertIn('d', sysconfig.get_config_var('ABIFLAGS')) + else: + self.assertNotIn('d', sysconfig.get_config_var('ABIFLAGS')) + if sysconfig.get_config_var('Py_GIL_DISABLED'): + self.assertIn('t', sysconfig.get_config_var('ABIFLAGS')) + else: + self.assertNotIn('t', sysconfig.get_config_var('ABIFLAGS')) + @requires_subprocess() def test_makefile_overwrites_config_vars(self): script = textwrap.dedent(""" From 97942b29fcf7d184a88793a3589da8aeb11f69b9 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Sat, 29 Mar 2025 03:13:34 +0800 Subject: [PATCH 12/43] Add tests --- Lib/test/test_sysconfig.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index f951af75b894ae..089d221149b0c2 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -595,20 +595,29 @@ def test_osx_ext_suffix(self): def test_always_set_ABIFLAGS(self): self.assertIn('ABIFLAGS', sysconfig.get_config_vars()) self.assertIsInstance(sysconfig.get_config_var('ABIFLAGS'), str) + self.assertIn('abiflags', sysconfig.get_config_vars()) + self.assertIsInstance(sysconfig.get_config_var('abiflags'), str) def test_always_set_Py_DEBUG(self): self.assertIn('Py_DEBUG', sysconfig.get_config_vars()) self.assertIn(sysconfig.get_config_var('Py_DEBUG'), (0, 1)) + def test_always_set_Py_GIL_DISABLED(self): + self.assertIn('Py_GIL_DISABLED', sysconfig.get_config_vars()) + self.assertIn(sysconfig.get_config_var('Py_GIL_DISABLED'), (0, 1)) + def test_ABIFLAGS(self): + abiflags = sysconfig.get_config_var('abiflags') + ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') + self.assertIn(abiflags, ABIFLAGS) if sysconfig.get_config_var('Py_DEBUG'): - self.assertIn('d', sysconfig.get_config_var('ABIFLAGS')) + self.assertIn('d', ABIFLAGS) else: - self.assertNotIn('d', sysconfig.get_config_var('ABIFLAGS')) + self.assertNotIn('d', ABIFLAGS) if sysconfig.get_config_var('Py_GIL_DISABLED'): - self.assertIn('t', sysconfig.get_config_var('ABIFLAGS')) + self.assertIn('t', ABIFLAGS) else: - self.assertNotIn('t', sysconfig.get_config_var('ABIFLAGS')) + self.assertNotIn('t', ABIFLAGS) @requires_subprocess() def test_makefile_overwrites_config_vars(self): From f49067e5441925c330735c5aa8e6e5d137c0d251 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Sat, 29 Mar 2025 03:35:59 +0800 Subject: [PATCH 13/43] Update tests --- Lib/test/test_sysconfig.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 089d221149b0c2..90eea625da2139 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -9,6 +9,7 @@ import textwrap from copy import copy +from test import support from test.support import ( captured_stdout, is_android, @@ -592,29 +593,38 @@ def test_osx_ext_suffix(self): suffix = sysconfig.get_config_var('EXT_SUFFIX') self.assertTrue(suffix.endswith('-darwin.so'), suffix) - def test_always_set_ABIFLAGS(self): + def test_always_set_abiflags(self): self.assertIn('ABIFLAGS', sysconfig.get_config_vars()) self.assertIsInstance(sysconfig.get_config_var('ABIFLAGS'), str) self.assertIn('abiflags', sysconfig.get_config_vars()) self.assertIsInstance(sysconfig.get_config_var('abiflags'), str) - def test_always_set_Py_DEBUG(self): + def test_always_set_py_debug(self): self.assertIn('Py_DEBUG', sysconfig.get_config_vars()) - self.assertIn(sysconfig.get_config_var('Py_DEBUG'), (0, 1)) + Py_DEBUG = sysconfig.get_config_var('Py_DEBUG') + self.assertIn(Py_DEBUG, (0, 1)) + self.assertEqual(Py_DEBUG, support.Py_DEBUG) - def test_always_set_Py_GIL_DISABLED(self): + def test_always_set_py_gil_disabled(self): self.assertIn('Py_GIL_DISABLED', sysconfig.get_config_vars()) - self.assertIn(sysconfig.get_config_var('Py_GIL_DISABLED'), (0, 1)) + Py_GIL_DISABLED = sysconfig.get_config_var('Py_GIL_DISABLED') + self.assertIn(Py_GIL_DISABLED, (0, 1)) + self.assertEqual(Py_GIL_DISABLED, support.Py_GIL_DISABLED) - def test_ABIFLAGS(self): + def test_abiflags(self): abiflags = sysconfig.get_config_var('abiflags') ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') + self.assertIn(abiflags, ABIFLAGS) - if sysconfig.get_config_var('Py_DEBUG'): + + if os.name == 'nt': + self.assertEqual(abiflags, '') + + if support.Py_DEBUG: self.assertIn('d', ABIFLAGS) else: self.assertNotIn('d', ABIFLAGS) - if sysconfig.get_config_var('Py_GIL_DISABLED'): + if support.Py_GIL_DISABLED: self.assertIn('t', ABIFLAGS) else: self.assertNotIn('t', ABIFLAGS) From 8fa952bab3b6352d34847b95068ad52e0f6ee2f2 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Sat, 29 Mar 2025 04:01:26 +0800 Subject: [PATCH 14/43] Update tests --- Lib/test/test_sys.py | 2 ++ Lib/test/test_sysconfig.py | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index c64a80d83f154e..1cec36fc0df6bd 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -719,6 +719,8 @@ def test_attributes(self): self.assertIn(sys.float_repr_style, ('short', 'legacy')) if not sys.platform.startswith('win'): self.assertIsInstance(sys.abiflags, str) + else: + self.assertFalse(hasattr(sys, 'abiflags')) def test_thread_info(self): info = sys.thread_info diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 90eea625da2139..7679ae2a3e76de 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -615,13 +615,17 @@ def test_abiflags(self): abiflags = sysconfig.get_config_var('abiflags') ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') + self.assertIsInstance(abiflags, str) + self.assertIsInstance(ABIFLAGS, str) self.assertIn(abiflags, ABIFLAGS) + if ABIFLAGS: + self.assertTrue(ABIFLAGS.isalpha(), ABIFLAGS) if os.name == 'nt': self.assertEqual(abiflags, '') if support.Py_DEBUG: - self.assertIn('d', ABIFLAGS) + self.assertEndsWith(ABIFLAGS, 'd') else: self.assertNotIn('d', ABIFLAGS) if support.Py_GIL_DISABLED: From b667dd9364105ee2c6bdb82f490c4cc6a483f3d9 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Mon, 31 Mar 2025 00:32:22 +0800 Subject: [PATCH 15/43] Remove unnecessary comments --- Lib/sysconfig/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index 759b8da1337e0c..e780b577c84870 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -406,7 +406,7 @@ def _init_non_posix(vars): # on Windows. sys.abiflags is absent on Windows and vars['abiflags'] # is already widely used to calculate paths, so it should remain an # empty string. - vars.update(_sysconfig.config_vars()) # defined in Modules/_sysconfig.c + vars.update(_sysconfig.config_vars()) vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs')) if hasattr(sys, 'dllhandle'): From 5df954061715c500310023a04a5fdb3360334d2a Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Mon, 31 Mar 2025 02:33:54 +0800 Subject: [PATCH 16/43] Update What's New --- Doc/whatsnew/3.14.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index ac5b53ef94bfb1..fada56fa6e063a 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -936,6 +936,14 @@ sys.monitoring * Two new events are added: :monitoring-event:`BRANCH_LEFT` and :monitoring-event:`BRANCH_RIGHT`. The ``BRANCH`` event is deprecated. + +sysconfig +--------- + +* Add ``ABIFLAGS`` key to :func:`sysconfig.get_config_vars` on Windows. + (Contributed by Xuehai Pan in :gh:`131799`.) + + threading --------- @@ -943,6 +951,7 @@ threading to :attr:`threading.Thread.name`. (Contributed by Victor Stinner in :gh:`59705`.) + tkinter ------- From 4f22ff3875aa1d53ba0a74d1dd290dcaae3bfb1a Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Mon, 31 Mar 2025 22:44:18 +0800 Subject: [PATCH 17/43] Revert `PCbuild/pyproject.props` --- PCbuild/pyproject.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index 83a34cf18961df..4e414dc913b9d5 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -42,7 +42,7 @@ <_DebugPreprocessorDefinition>NDEBUG; - <_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG;Py_DEBUG; + <_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG; <_PyStatsPreprocessorDefinition>PyStats; <_PyStatsPreprocessorDefinition Condition="$(PySTATS) != ''">Py_STATS; <_PlatformPreprocessorDefinition>_WIN32; From a4646c541cd18eb5aa0468d99153a928b48c750b Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Mon, 31 Mar 2025 23:04:45 +0800 Subject: [PATCH 18/43] Revert `_DEBUG` -> `Py_DEBUG` --- PC/launcher.c | 2 +- PC/pyconfig.h.in | 17 ++++++++--------- PC/python_uwp.cpp | 4 ++-- PC/python_ver_rc.h | 2 +- Python/dynload_win.c | 6 +++--- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/PC/launcher.c b/PC/launcher.c index 40e6630b82e17a..47fafbc3bf6bad 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -140,7 +140,7 @@ static wchar_t * get_env(wchar_t * key) return buf; } -#if defined(Py_DEBUG) +#if defined(_DEBUG) /* Do not define EXECUTABLEPATH_VALUE in debug builds as it'll never point to the debug build. */ #if defined(_WINDOWS) diff --git a/PC/pyconfig.h.in b/PC/pyconfig.h.in index f29a62eb45b0bb..9e70303868e5de 100644 --- a/PC/pyconfig.h.in +++ b/PC/pyconfig.h.in @@ -102,11 +102,6 @@ WIN32 is still required for the locale module. /* #define Py_GIL_DISABLED 1 */ #endif -// _DEBUG implies Py_DEBUG -#ifdef _DEBUG -#define Py_DEBUG -#endif - /* Compiler specific defines */ /* ------------------------------------------------------------------------*/ @@ -324,21 +319,21 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ This is relevant when using build-system generator (e.g CMake) where the linking is explicitly handled */ # if defined(Py_GIL_DISABLED) -# if defined(Py_DEBUG) +# if defined(_DEBUG) # pragma comment(lib,"python314t_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3t.lib") # else # pragma comment(lib,"python314t.lib") -# endif /* Py_DEBUG */ +# endif /* _DEBUG */ # else /* Py_GIL_DISABLED */ -# if defined(Py_DEBUG) +# if defined(_DEBUG) # pragma comment(lib,"python314_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3.lib") # else # pragma comment(lib,"python314.lib") -# endif /* Py_DEBUG */ +# endif /* _DEBUG */ # endif /* Py_GIL_DISABLED */ # endif /* _MSC_VER && !Py_NO_LINK_LIB */ # endif /* Py_BUILD_CORE */ @@ -381,6 +376,10 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ # define ALIGNOF_MAX_ALIGN_T 8 #endif +#ifdef _DEBUG +# define Py_DEBUG +#endif + #ifdef MS_WIN32 diff --git a/PC/python_uwp.cpp b/PC/python_uwp.cpp index 8cdb8d722cdb9a..b9c408a580c999 100644 --- a/PC/python_uwp.cpp +++ b/PC/python_uwp.cpp @@ -19,13 +19,13 @@ #include #ifdef PYTHONW -#ifdef Py_DEBUG +#ifdef _DEBUG const wchar_t *PROGNAME = L"pythonw_d.exe"; #else const wchar_t *PROGNAME = L"pythonw.exe"; #endif #else -#ifdef Py_DEBUG +#ifdef _DEBUG const wchar_t *PROGNAME = L"python_d.exe"; #else const wchar_t *PROGNAME = L"python.exe"; diff --git a/PC/python_ver_rc.h b/PC/python_ver_rc.h index bb98144cd03f15..ee867fe41224c3 100644 --- a/PC/python_ver_rc.h +++ b/PC/python_ver_rc.h @@ -10,7 +10,7 @@ #define MS_WINDOWS #include "modsupport.h" #include "patchlevel.h" -#ifdef Py_DEBUG +#ifdef _DEBUG # define PYTHON_DEBUG_EXT "_d" #else # define PYTHON_DEBUG_EXT diff --git a/Python/dynload_win.c b/Python/dynload_win.c index de9b0a77817a63..6324063401e51f 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -108,7 +108,7 @@ static char *GetPythonImport (HINSTANCE hModule) char *pch; /* Don't claim that python3.dll is a Python DLL. */ -#ifdef Py_DEBUG +#ifdef _DEBUG if (strcmp(import_name, "python3_d.dll") == 0) { #else if (strcmp(import_name, "python3.dll") == 0) { @@ -120,7 +120,7 @@ static char *GetPythonImport (HINSTANCE hModule) /* Ensure python prefix is followed only by numbers to the end of the basename */ pch = import_name + 6; -#ifdef Py_DEBUG +#ifdef _DEBUG while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') { #else while (*pch && *pch != '.') { @@ -300,7 +300,7 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, char buffer[256]; PyOS_snprintf(buffer, sizeof(buffer), -#ifdef Py_DEBUG +#ifdef _DEBUG "python%d%d_d.dll", #else "python%d%d.dll", From 7b21d7d90bc7163ab9548a8d801a8f0a2d3a7212 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Mon, 31 Mar 2025 23:07:18 +0800 Subject: [PATCH 19/43] Revert `_DEBUG` -> `Py_DEBUG` --- Include/internal/pycore_importdl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/internal/pycore_importdl.h b/Include/internal/pycore_importdl.h index 3ba9229cc21378..525a16f6b97274 100644 --- a/Include/internal/pycore_importdl.h +++ b/Include/internal/pycore_importdl.h @@ -107,7 +107,7 @@ extern int _PyImport_RunModInitFunc( #include typedef FARPROC dl_funcptr; -#ifdef Py_DEBUG +#ifdef _DEBUG # define PYD_DEBUG_SUFFIX "_d" #else # define PYD_DEBUG_SUFFIX "" From 1ee82303c7416a0b0909b71a1a43de47b5c7d002 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Mon, 31 Mar 2025 23:09:11 +0800 Subject: [PATCH 20/43] Add underscore prefix to `d` on Windows --- Lib/sysconfig/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index e780b577c84870..9f411e377d06a3 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -408,6 +408,9 @@ def _init_non_posix(vars): # empty string. vars.update(_sysconfig.config_vars()) + # Add an underscore to the `d` flag. E.g, `td` -> `t_d`, `d` -> `_d`. + vars['Py_DEBUG'] = vars['Py_DEBUG'].replace('d', '_d') + vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs')) if hasattr(sys, 'dllhandle'): dllhandle = _winapi.GetModuleFileName(sys.dllhandle) From 084deac14b8808e522fca18e55c01f02002be509 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Mon, 31 Mar 2025 23:40:33 +0800 Subject: [PATCH 21/43] Fix key name --- Lib/sysconfig/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index 9f411e377d06a3..34e29be9f61621 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -409,7 +409,7 @@ def _init_non_posix(vars): vars.update(_sysconfig.config_vars()) # Add an underscore to the `d` flag. E.g, `td` -> `t_d`, `d` -> `_d`. - vars['Py_DEBUG'] = vars['Py_DEBUG'].replace('d', '_d') + vars['ABIFLAGS'] = vars['ABIFLAGS'].replace('d', '_d') vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs')) if hasattr(sys, 'dllhandle'): From af50632b02abcb1de18e91177fddaf6b570ce0c1 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Mon, 31 Mar 2025 23:46:49 +0800 Subject: [PATCH 22/43] Add comments for test for `d` flag in `ABIFLAGS` --- Lib/test/test_sysconfig.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 7679ae2a3e76de..7f3807712aad8d 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -625,6 +625,9 @@ def test_abiflags(self): self.assertEqual(abiflags, '') if support.Py_DEBUG: + # The 'd' flag should always be the last one. + # On Windows, the debug flag is used differently with a underscore prefix. + # For example, `python{X}.{Y}td` on Unix and ```python{X}.{Y}t_d.exe` on Windows. self.assertEndsWith(ABIFLAGS, 'd') else: self.assertNotIn('d', ABIFLAGS) From b397f406f3407a5f2cf6d0ea604a5d9fb07d6a16 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 1 Apr 2025 00:06:17 +0800 Subject: [PATCH 23/43] Fix failing test --- Lib/test/test_sysconfig.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 7f3807712aad8d..0909b6e8a02303 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -619,7 +619,8 @@ def test_abiflags(self): self.assertIsInstance(ABIFLAGS, str) self.assertIn(abiflags, ABIFLAGS) if ABIFLAGS: - self.assertTrue(ABIFLAGS.isalpha(), ABIFLAGS) + self.assertLessEqual(ABIFLAGS.count('_'), 1) # example value on Windows: 't_d' + self.assertTrue(ABIFLAGS.replace('_', '').isalpha(), ABIFLAGS) if os.name == 'nt': self.assertEqual(abiflags, '') From 1a82cd1b979103178cd3a384d3e763b60c9b27a9 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 1 Apr 2025 00:08:15 +0800 Subject: [PATCH 24/43] Update tests --- Lib/test/test_sysconfig.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 0909b6e8a02303..fcb8c954659a03 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -618,17 +618,21 @@ def test_abiflags(self): self.assertIsInstance(abiflags, str) self.assertIsInstance(ABIFLAGS, str) self.assertIn(abiflags, ABIFLAGS) - if ABIFLAGS: - self.assertLessEqual(ABIFLAGS.count('_'), 1) # example value on Windows: 't_d' - self.assertTrue(ABIFLAGS.replace('_', '').isalpha(), ABIFLAGS) if os.name == 'nt': self.assertEqual(abiflags, '') + # Example values: '', 't', 't_d', '_d' + self.assertLessEqual(ABIFLAGS.count('_'), 1) + else: + # Example values: '', 't', 'td', 'd' + self.assertNotIn('_', ABIFLAGS) + if ABIFLAGS: + self.assertTrue(ABIFLAGS.replace('_', '').isalpha(), ABIFLAGS) if support.Py_DEBUG: # The 'd' flag should always be the last one. # On Windows, the debug flag is used differently with a underscore prefix. - # For example, `python{X}.{Y}td` on Unix and ```python{X}.{Y}t_d.exe` on Windows. + # For example, `python{X}.{Y}td` on Unix and `python{X}.{Y}t_d.exe` on Windows. self.assertEndsWith(ABIFLAGS, 'd') else: self.assertNotIn('d', ABIFLAGS) From 518137beb3fe864fe86514dd810ab22c809526bc Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 4 Apr 2025 03:21:03 +0800 Subject: [PATCH 25/43] Add a test for `sysconfig.get_config_var('ABIFLAGS')` on Windows --- Lib/test/test_winapi.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Lib/test/test_winapi.py b/Lib/test/test_winapi.py index e64208330ad2f9..9fc1cf97b43406 100644 --- a/Lib/test/test_winapi.py +++ b/Lib/test/test_winapi.py @@ -3,6 +3,8 @@ import os import pathlib import re +import sys +import sysconfig import unittest from test.support import import_helper, os_helper @@ -156,3 +158,14 @@ def test_namedpipe(self): pipe2.write(b'testdata') pipe2.flush() self.assertEqual((b'testdata', 8), _winapi.PeekNamedPipe(pipe, 8)[:2]) + + def test_get_module_file_name(self): + dll_file_path = _winapi.GetModuleFileName(sys.dllhandle) + dll_file_name = os.path.basename(dll_file_path) + self.assertEqual( + dll_file_name, + "python{vi.major}{vi.minor}{abiflags}.dll".format( + vi=sys.version_info, + abiflags=sysconfig.get_config_var('ABIFLAGS'), + ), + ) From 486e2a880c043f17a6b9f38c93f3286d36b41ad8 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 4 Apr 2025 03:22:33 +0800 Subject: [PATCH 26/43] Rename test function --- Lib/test/test_winapi.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_winapi.py b/Lib/test/test_winapi.py index 9fc1cf97b43406..a69740cb696e72 100644 --- a/Lib/test/test_winapi.py +++ b/Lib/test/test_winapi.py @@ -127,6 +127,17 @@ def test_getshortpathname(self): # Should contain "PROGRA~" but we can't predict the number self.assertIsNotNone(re.match(r".\:\\PROGRA~\d", actual.upper()), actual) + def test_getmodulefilename(self): + dll_file_path = _winapi.GetModuleFileName(sys.dllhandle) + dll_file_name = os.path.basename(dll_file_path) + self.assertEqual( + dll_file_name, + "python{vi.major}{vi.minor}{abiflags}.dll".format( + vi=sys.version_info, + abiflags=sysconfig.get_config_var('ABIFLAGS'), + ), + ) + def test_namedpipe(self): pipe_name = rf"\\.\pipe\LOCAL\{os_helper.TESTFN}" @@ -158,14 +169,3 @@ def test_namedpipe(self): pipe2.write(b'testdata') pipe2.flush() self.assertEqual((b'testdata', 8), _winapi.PeekNamedPipe(pipe, 8)[:2]) - - def test_get_module_file_name(self): - dll_file_path = _winapi.GetModuleFileName(sys.dllhandle) - dll_file_name = os.path.basename(dll_file_path) - self.assertEqual( - dll_file_name, - "python{vi.major}{vi.minor}{abiflags}.dll".format( - vi=sys.version_info, - abiflags=sysconfig.get_config_var('ABIFLAGS'), - ), - ) From 3bccf1db8566a7960ca10bac0ebc7e52c80de7e8 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 4 Apr 2025 03:45:01 +0800 Subject: [PATCH 27/43] Move test location --- Lib/test/test_sysconfig.py | 11 +++++------ Lib/test/test_winapi.py | 11 ----------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 255a94e35814cf..12222f7f37165e 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -456,20 +456,19 @@ def test_library(self): library = sysconfig.get_config_var('LIBRARY') ldlibrary = sysconfig.get_config_var('LDLIBRARY') major, minor = sys.version_info[:2] - if sys.platform == 'win32': - self.assertTrue(library.startswith(f'python{major}{minor}')) - self.assertTrue(library.endswith('.dll')) + abiflags = sysconfig.get_config_var('ABIFLAGS') + if sys.platform.startswith('win'): + self.assertEqual(library, f'python{major}{minor}{abiflags}.dll') self.assertEqual(library, ldlibrary) elif is_apple_mobile: framework = sysconfig.get_config_var('PYTHONFRAMEWORK') self.assertEqual(ldlibrary, f"{framework}.framework/{framework}") else: - self.assertTrue(library.startswith(f'libpython{major}.{minor}')) - self.assertTrue(library.endswith('.a')) + self.assertEqual(library, f'libpython{major}.{minor}{abiflags}.a') if sys.platform == 'darwin' and sys._framework: self.skipTest('gh-110824: skip LDLIBRARY test for framework build') else: - self.assertTrue(ldlibrary.startswith(f'libpython{major}.{minor}')) + self.assertStartsWith(ldlibrary, f'libpython{major}.{minor}{abiflags}') @unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX") @requires_subprocess() diff --git a/Lib/test/test_winapi.py b/Lib/test/test_winapi.py index a69740cb696e72..ba56277ad6a3f4 100644 --- a/Lib/test/test_winapi.py +++ b/Lib/test/test_winapi.py @@ -127,17 +127,6 @@ def test_getshortpathname(self): # Should contain "PROGRA~" but we can't predict the number self.assertIsNotNone(re.match(r".\:\\PROGRA~\d", actual.upper()), actual) - def test_getmodulefilename(self): - dll_file_path = _winapi.GetModuleFileName(sys.dllhandle) - dll_file_name = os.path.basename(dll_file_path) - self.assertEqual( - dll_file_name, - "python{vi.major}{vi.minor}{abiflags}.dll".format( - vi=sys.version_info, - abiflags=sysconfig.get_config_var('ABIFLAGS'), - ), - ) - def test_namedpipe(self): pipe_name = rf"\\.\pipe\LOCAL\{os_helper.TESTFN}" From 780f3408a93f9a603f3fb8034128ee968eb11ed2 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 4 Apr 2025 03:46:35 +0800 Subject: [PATCH 28/43] Move test location --- Lib/test/test_winapi.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/test/test_winapi.py b/Lib/test/test_winapi.py index ba56277ad6a3f4..e64208330ad2f9 100644 --- a/Lib/test/test_winapi.py +++ b/Lib/test/test_winapi.py @@ -3,8 +3,6 @@ import os import pathlib import re -import sys -import sysconfig import unittest from test.support import import_helper, os_helper From 98c26f9cdee724833acd136a632ff2e4e789dcf1 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 4 Apr 2025 04:04:56 +0800 Subject: [PATCH 29/43] Add a note for `test_abiflags` --- Lib/test/test_sysconfig.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 12222f7f37165e..3c0ec3fef32a20 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -611,6 +611,8 @@ def test_always_set_py_gil_disabled(self): self.assertEqual(Py_GIL_DISABLED, support.Py_GIL_DISABLED) def test_abiflags(self): + # XXX: If this test fails on some platforms, maintainers should add/update + # the definition of the ABIFLAGS variable and make this test pass. abiflags = sysconfig.get_config_var('abiflags') ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') @@ -621,7 +623,7 @@ def test_abiflags(self): if os.name == 'nt': self.assertEqual(abiflags, '') # Example values: '', 't', 't_d', '_d' - self.assertLessEqual(ABIFLAGS.count('_'), 1) + self.assertTrue(ABIFLAGS.count('_d') == 1 or '_' not in ABIFLAGS, ABIFLAGS) else: # Example values: '', 't', 'td', 'd' self.assertNotIn('_', ABIFLAGS) From e236bc75fbfb13725553f228a62f10b0bf8a75ae Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 4 Apr 2025 04:35:54 +0800 Subject: [PATCH 30/43] Move definition of ABIFLAGS from C to Python --- Lib/sysconfig/__init__.py | 14 +++++++++----- Modules/_sysconfig.c | 17 ----------------- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py index 34e29be9f61621..dad715eb087387 100644 --- a/Lib/sysconfig/__init__.py +++ b/Lib/sysconfig/__init__.py @@ -401,15 +401,19 @@ def _init_non_posix(vars): vars['BINLIBDEST'] = get_path('platstdlib') vars['INCLUDEPY'] = get_path('include') - # Add EXT_SUFFIX, SOABI, ABIFLAGS, Py_DEBUG, and Py_GIL_DISABLED + # Add EXT_SUFFIX, SOABI, Py_DEBUG, and Py_GIL_DISABLED + vars.update(_sysconfig.config_vars()) + # NOTE: ABIFLAGS is only an emulated value. It is not present during build # on Windows. sys.abiflags is absent on Windows and vars['abiflags'] # is already widely used to calculate paths, so it should remain an # empty string. - vars.update(_sysconfig.config_vars()) - - # Add an underscore to the `d` flag. E.g, `td` -> `t_d`, `d` -> `_d`. - vars['ABIFLAGS'] = vars['ABIFLAGS'].replace('d', '_d') + vars['ABIFLAGS'] = ''.join( + ( + 't' if vars['Py_GIL_DISABLED'] else '', + '_d' if vars['Py_DEBUG'] else '', + ), + ) vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs')) if hasattr(sys, 'dllhandle'): diff --git a/Modules/_sysconfig.c b/Modules/_sysconfig.c index 728cb4b252f2e3..e2d141b5910b6d 100644 --- a/Modules/_sysconfig.c +++ b/Modules/_sysconfig.c @@ -55,23 +55,6 @@ _sysconfig_config_vars_impl(PyObject *module) Py_DECREF(config); return NULL; } - - // On Unix, the `ABIFLAGS` key is defined via a different logic. - // - // Emulate `sys.abiflags` value on Unix for Windows. ABIFLAGS here is only - // an emulated value. It is not present during build on Windows. - if (add_string_value(config, "ABIFLAGS", -# ifdef Py_GIL_DISABLED - "t" -# endif -# ifdef Py_DEBUG - "d" -# endif - "") - < 0) { - Py_DECREF(config); - return NULL; - } #endif #ifdef Py_GIL_DISABLED From 299cec6b3025b336bb5406a91a39e1459634c512 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 8 Apr 2025 05:57:29 +0800 Subject: [PATCH 31/43] Update tests --- Lib/test/test_sysconfig.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 3c0ec3fef32a20..c460b56a00e35e 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -611,7 +611,7 @@ def test_always_set_py_gil_disabled(self): self.assertEqual(Py_GIL_DISABLED, support.Py_GIL_DISABLED) def test_abiflags(self): - # XXX: If this test fails on some platforms, maintainers should add/update + # If this test fails on some platforms, maintainers should add/update # the definition of the ABIFLAGS variable and make this test pass. abiflags = sysconfig.get_config_var('abiflags') ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') @@ -620,10 +620,17 @@ def test_abiflags(self): self.assertIsInstance(ABIFLAGS, str) self.assertIn(abiflags, ABIFLAGS) + # Check all flags are alphabetic if os.name == 'nt': self.assertEqual(abiflags, '') # Example values: '', 't', 't_d', '_d' - self.assertTrue(ABIFLAGS.count('_d') == 1 or '_' not in ABIFLAGS, ABIFLAGS) + # '_' can only exist if 'd' is present + if '_' in ABIFLAGS: + # '_' is followed by 'd' + self.assertTrue(ABIFLAGS.count('_d') == 1, ABIFLAGS) + self.assertTrue(ABIFLAGS.count('_') == 1, ABIFLAGS) + else: + self.assertNotIn('d', ABIFLAGS) else: # Example values: '', 't', 'td', 'd' self.assertNotIn('_', ABIFLAGS) From 21d2e738f8b4e7a19ce00bb9d706e14344547ad5 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 8 Apr 2025 06:42:07 +0800 Subject: [PATCH 32/43] Split 't' flag to another test --- Lib/test/test_sysconfig.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index c460b56a00e35e..b8ba71b5cc4d5a 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -644,9 +644,16 @@ def test_abiflags(self): self.assertEndsWith(ABIFLAGS, 'd') else: self.assertNotIn('d', ABIFLAGS) + + def test_abi_thread(self): + abi_thread = sysconfig.get_config_var('abi_thread') + ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') + self.assertIsInstance(abi_thread, str) if support.Py_GIL_DISABLED: + self.assertEqual(abi_thread, 't') self.assertIn('t', ABIFLAGS) else: + self.assertEqual(abi_thread, '') self.assertNotIn('t', ABIFLAGS) @requires_subprocess() From d265a596ecc456f749383f6a3fbd65866c905588 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 8 Apr 2025 12:00:04 +0800 Subject: [PATCH 33/43] Update tests --- Lib/test/test_sysconfig.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index b8ba71b5cc4d5a..ab46606ac2ec4c 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -611,8 +611,8 @@ def test_always_set_py_gil_disabled(self): self.assertEqual(Py_GIL_DISABLED, support.Py_GIL_DISABLED) def test_abiflags(self): - # If this test fails on some platforms, maintainers should add/update - # the definition of the ABIFLAGS variable and make this test pass. + # If this test fails on some platforms, maintainers should update the + # test to make it pass, rather than changing the definition of ABIFLAGS. abiflags = sysconfig.get_config_var('abiflags') ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') @@ -621,21 +621,23 @@ def test_abiflags(self): self.assertIn(abiflags, ABIFLAGS) # Check all flags are alphabetic + valid_abiflags = ('', 't', 'd', 'td') + for flags in valid_abiflags: + self.assertTrue(len(flags) == len(set(flags)), flags) + if flags: + self.assertIn(flags.isalpha(), flags) if os.name == 'nt': self.assertEqual(abiflags, '') # Example values: '', 't', 't_d', '_d' # '_' can only exist if 'd' is present - if '_' in ABIFLAGS: - # '_' is followed by 'd' - self.assertTrue(ABIFLAGS.count('_d') == 1, ABIFLAGS) - self.assertTrue(ABIFLAGS.count('_') == 1, ABIFLAGS) - else: - self.assertNotIn('d', ABIFLAGS) + # '_' can only followed by 'd' + self.assertIn( + ABIFLAGS, + tuple(flag.replace('d', '_d') for flag in valid_abiflags), + ) else: # Example values: '', 't', 'td', 'd' - self.assertNotIn('_', ABIFLAGS) - if ABIFLAGS: - self.assertTrue(ABIFLAGS.replace('_', '').isalpha(), ABIFLAGS) + self.assertIn(ABIFLAGS, valid_abiflags) if support.Py_DEBUG: # The 'd' flag should always be the last one. From f3b857016cc396711514867d8af3e55eea7ca937 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 8 Apr 2025 12:02:18 +0800 Subject: [PATCH 34/43] Update tests --- Lib/test/test_sysconfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index ab46606ac2ec4c..f79d5594fe7d7b 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -633,7 +633,7 @@ def test_abiflags(self): # '_' can only followed by 'd' self.assertIn( ABIFLAGS, - tuple(flag.replace('d', '_d') for flag in valid_abiflags), + tuple(flags.replace('d', '_d') for flags in valid_abiflags), ) else: # Example values: '', 't', 'td', 'd' From fe4ea953b0717a9cea856fd32c4a954670b79422 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 8 Apr 2025 12:05:54 +0800 Subject: [PATCH 35/43] Update tests --- Lib/test/test_sysconfig.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index f79d5594fe7d7b..8b3d94bed93cd2 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -620,15 +620,14 @@ def test_abiflags(self): self.assertIsInstance(ABIFLAGS, str) self.assertIn(abiflags, ABIFLAGS) - # Check all flags are alphabetic valid_abiflags = ('', 't', 'd', 'td') - for flags in valid_abiflags: + for flags in valid_abiflags: # senity check self.assertTrue(len(flags) == len(set(flags)), flags) if flags: self.assertIn(flags.isalpha(), flags) if os.name == 'nt': self.assertEqual(abiflags, '') - # Example values: '', 't', 't_d', '_d' + # Example values: '', '_d', 't', 't_d' # '_' can only exist if 'd' is present # '_' can only followed by 'd' self.assertIn( @@ -636,9 +635,11 @@ def test_abiflags(self): tuple(flags.replace('d', '_d') for flags in valid_abiflags), ) else: - # Example values: '', 't', 'td', 'd' + # Example values: '', 'd', 't', 'td' self.assertIn(ABIFLAGS, valid_abiflags) + def test_abi_debug(self): + ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') if support.Py_DEBUG: # The 'd' flag should always be the last one. # On Windows, the debug flag is used differently with a underscore prefix. From 64f096121edf54d8827ee701c3f0ec9630810f1a Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 8 Apr 2025 23:24:41 +0800 Subject: [PATCH 36/43] Simplify tests --- Lib/test/test_sysconfig.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 8b3d94bed93cd2..e37b8dfcdf5944 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -592,12 +592,6 @@ def test_osx_ext_suffix(self): suffix = sysconfig.get_config_var('EXT_SUFFIX') self.assertTrue(suffix.endswith('-darwin.so'), suffix) - def test_always_set_abiflags(self): - self.assertIn('ABIFLAGS', sysconfig.get_config_vars()) - self.assertIsInstance(sysconfig.get_config_var('ABIFLAGS'), str) - self.assertIn('abiflags', sysconfig.get_config_vars()) - self.assertIsInstance(sysconfig.get_config_var('abiflags'), str) - def test_always_set_py_debug(self): self.assertIn('Py_DEBUG', sysconfig.get_config_vars()) Py_DEBUG = sysconfig.get_config_var('Py_DEBUG') @@ -613,29 +607,23 @@ def test_always_set_py_gil_disabled(self): def test_abiflags(self): # If this test fails on some platforms, maintainers should update the # test to make it pass, rather than changing the definition of ABIFLAGS. + self.assertIn('ABIFLAGS', sysconfig.get_config_vars()) + self.assertIn('abiflags', sysconfig.get_config_vars()) abiflags = sysconfig.get_config_var('abiflags') ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') - self.assertIsInstance(abiflags, str) self.assertIsInstance(ABIFLAGS, str) self.assertIn(abiflags, ABIFLAGS) valid_abiflags = ('', 't', 'd', 'td') - for flags in valid_abiflags: # senity check - self.assertTrue(len(flags) == len(set(flags)), flags) - if flags: - self.assertIn(flags.isalpha(), flags) if os.name == 'nt': self.assertEqual(abiflags, '') - # Example values: '', '_d', 't', 't_d' - # '_' can only exist if 'd' is present - # '_' can only followed by 'd' + # '_' can only exist if 'd' is present and can only followed by 'd' self.assertIn( ABIFLAGS, tuple(flags.replace('d', '_d') for flags in valid_abiflags), ) else: - # Example values: '', 'd', 't', 'td' self.assertIn(ABIFLAGS, valid_abiflags) def test_abi_debug(self): From 8b164547cccdde14e1ff784b0852abc3f27b8453 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 8 Apr 2025 23:30:35 +0800 Subject: [PATCH 37/43] Simplify tests --- Lib/test/test_sysconfig.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index e37b8dfcdf5944..1843b35722a274 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -615,16 +615,15 @@ def test_abiflags(self): self.assertIsInstance(ABIFLAGS, str) self.assertIn(abiflags, ABIFLAGS) - valid_abiflags = ('', 't', 'd', 'td') + if not sys.platform.startswith('win'): + valid_abiflags = ('', 't', 'd', 'td') + else: + # '_' can only exist if 'd' is present and can only followed by 'd' + valid_abiflags = ('', 't', '_d', 't_d') + if os.name == 'nt': self.assertEqual(abiflags, '') - # '_' can only exist if 'd' is present and can only followed by 'd' - self.assertIn( - ABIFLAGS, - tuple(flags.replace('d', '_d') for flags in valid_abiflags), - ) - else: - self.assertIn(ABIFLAGS, valid_abiflags) + self.assertIn(ABIFLAGS, valid_abiflags) def test_abi_debug(self): ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') From 1c807f0c92848d4da56f8d96d1e7578cb309a41a Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 8 Apr 2025 23:34:27 +0800 Subject: [PATCH 38/43] Update test comments --- Lib/test/test_sysconfig.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 1843b35722a274..bae1548caaccbc 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -607,8 +607,8 @@ def test_always_set_py_gil_disabled(self): def test_abiflags(self): # If this test fails on some platforms, maintainers should update the # test to make it pass, rather than changing the definition of ABIFLAGS. - self.assertIn('ABIFLAGS', sysconfig.get_config_vars()) self.assertIn('abiflags', sysconfig.get_config_vars()) + self.assertIn('ABIFLAGS', sysconfig.get_config_vars()) abiflags = sysconfig.get_config_var('abiflags') ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') self.assertIsInstance(abiflags, str) @@ -618,7 +618,9 @@ def test_abiflags(self): if not sys.platform.startswith('win'): valid_abiflags = ('', 't', 'd', 'td') else: - # '_' can only exist if 'd' is present and can only followed by 'd' + # '_' can only exist if 'd' is present and can only followed by 'd'. + # That is `ABIFLAGS.replace('d', '_d')` above. + # See test_abi_debug() for more details. valid_abiflags = ('', 't', '_d', 't_d') if os.name == 'nt': From 932386c6a3c554d6fd7cea778e6c53b80bca4118 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Thu, 10 Apr 2025 01:26:37 +0800 Subject: [PATCH 39/43] Simplify test comment --- Lib/test/test_sysconfig.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index bae1548caaccbc..bc52d01634e506 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -618,9 +618,7 @@ def test_abiflags(self): if not sys.platform.startswith('win'): valid_abiflags = ('', 't', 'd', 'td') else: - # '_' can only exist if 'd' is present and can only followed by 'd'. - # That is `ABIFLAGS.replace('d', '_d')` above. - # See test_abi_debug() for more details. + # These are mapped with `f.replace('d', '_d')` above. See test_abi_debug(). valid_abiflags = ('', 't', '_d', 't_d') if os.name == 'nt': From 23b6e6c77b3146362e4c7562d29ad7b04e70bb85 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Thu, 10 Apr 2025 01:50:45 +0800 Subject: [PATCH 40/43] Apply suggestions from code review --- Lib/test/test_sysconfig.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index bc52d01634e506..fdb28eddcd2491 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -614,15 +614,15 @@ def test_abiflags(self): self.assertIsInstance(abiflags, str) self.assertIsInstance(ABIFLAGS, str) self.assertIn(abiflags, ABIFLAGS) + if os.name == 'nt': + self.assertEqual(abiflags, '') if not sys.platform.startswith('win'): valid_abiflags = ('', 't', 'd', 'td') else: - # These are mapped with `f.replace('d', '_d')` above. See test_abi_debug(). + # Windows uses '_d' rather than 'd'; see also test_abi_debug below valid_abiflags = ('', 't', '_d', 't_d') - if os.name == 'nt': - self.assertEqual(abiflags, '') self.assertIn(ABIFLAGS, valid_abiflags) def test_abi_debug(self): From 75b6c51a74f678052ad3be567da578a162f884bc Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 11 Apr 2025 19:18:35 +0800 Subject: [PATCH 41/43] Make 'd' flag test more platform specific --- Lib/test/test_sysconfig.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index fdb28eddcd2491..2b3c80e1eb38c5 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -628,13 +628,16 @@ def test_abiflags(self): def test_abi_debug(self): ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') if support.Py_DEBUG: - # The 'd' flag should always be the last one. - # On Windows, the debug flag is used differently with a underscore prefix. - # For example, `python{X}.{Y}td` on Unix and `python{X}.{Y}t_d.exe` on Windows. - self.assertEndsWith(ABIFLAGS, 'd') + self.assertIn('d', ABIFLAGS) else: self.assertNotIn('d', ABIFLAGS) + # The 'd' flag should always be the last one on Windows. + # On Windows, the debug flag is used differently with a underscore prefix. + # For example, `python{X}.{Y}td` on Unix and `python{X}.{Y}t_d.exe` on Windows. + if support.Py_DEBUG and sys.platform.endswith('win'): + self.assertEndsWith(ABIFLAGS, '_d') + def test_abi_thread(self): abi_thread = sysconfig.get_config_var('abi_thread') ABIFLAGS = sysconfig.get_config_var('ABIFLAGS') From d55b3e6717553e7caf2c01a2664a5e2e93c80a4e Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 11 Apr 2025 19:21:26 +0800 Subject: [PATCH 42/43] Revert non-Windows test changes --- Lib/test/test_sysconfig.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 2b3c80e1eb38c5..2424f1fb310b5f 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -464,11 +464,12 @@ def test_library(self): framework = sysconfig.get_config_var('PYTHONFRAMEWORK') self.assertEqual(ldlibrary, f"{framework}.framework/{framework}") else: - self.assertEqual(library, f'libpython{major}.{minor}{abiflags}.a') + self.assertStartsWith(library, f'libpython{major}.{minor}') + self.assertEndsWith(library, '.a') if sys.platform == 'darwin' and sys._framework: self.skipTest('gh-110824: skip LDLIBRARY test for framework build') else: - self.assertStartsWith(ldlibrary, f'libpython{major}.{minor}{abiflags}') + self.assertStartsWith(ldlibrary, f'libpython{major}.{minor}') @unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX") @requires_subprocess() From a0840707ba6672ab629553b80ea540048ad64574 Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Fri, 11 Apr 2025 19:41:36 +0800 Subject: [PATCH 43/43] Fix Windows platform detection --- Lib/test/test_sysconfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 2424f1fb310b5f..53e55383bf9c72 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -636,7 +636,7 @@ def test_abi_debug(self): # The 'd' flag should always be the last one on Windows. # On Windows, the debug flag is used differently with a underscore prefix. # For example, `python{X}.{Y}td` on Unix and `python{X}.{Y}t_d.exe` on Windows. - if support.Py_DEBUG and sys.platform.endswith('win'): + if support.Py_DEBUG and sys.platform.startswith('win'): self.assertEndsWith(ABIFLAGS, '_d') def test_abi_thread(self): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy