gh-127405: Add ABIFLAGS to sysconfig variables on Windows (GH-131799)

This commit is contained in:
Xuehai Pan 2025-04-11 23:19:03 +08:00 committed by GitHub
parent 9ded6f0830
commit 26ae05e95c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 99 additions and 7 deletions

View file

@ -1078,6 +1078,14 @@ sys.monitoring
* Two new events are added: :monitoring-event:`BRANCH_LEFT` and * Two new events are added: :monitoring-event:`BRANCH_LEFT` and
:monitoring-event:`BRANCH_RIGHT`. The ``BRANCH`` event is deprecated. :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 threading
--------- ---------
@ -1085,6 +1093,7 @@ threading
to :attr:`threading.Thread.name`. to :attr:`threading.Thread.name`.
(Contributed by Victor Stinner in :gh:`59705`.) (Contributed by Victor Stinner in :gh:`59705`.)
tkinter tkinter
------- -------

View file

@ -401,9 +401,20 @@ def _init_non_posix(vars):
vars['BINLIBDEST'] = get_path('platstdlib') vars['BINLIBDEST'] = get_path('platstdlib')
vars['INCLUDEPY'] = get_path('include') vars['INCLUDEPY'] = get_path('include')
# Add EXT_SUFFIX, SOABI, and Py_GIL_DISABLED # Add EXT_SUFFIX, SOABI, Py_DEBUG, and Py_GIL_DISABLED
vars.update(_sysconfig.config_vars()) 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['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')) vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs'))
if hasattr(sys, 'dllhandle'): if hasattr(sys, 'dllhandle'):
dllhandle = _winapi.GetModuleFileName(sys.dllhandle) dllhandle = _winapi.GetModuleFileName(sys.dllhandle)

View file

@ -724,6 +724,8 @@ class SysModuleTest(unittest.TestCase):
self.assertIn(sys.float_repr_style, ('short', 'legacy')) self.assertIn(sys.float_repr_style, ('short', 'legacy'))
if not sys.platform.startswith('win'): if not sys.platform.startswith('win'):
self.assertIsInstance(sys.abiflags, str) self.assertIsInstance(sys.abiflags, str)
else:
self.assertFalse(hasattr(sys, 'abiflags'))
def test_thread_info(self): def test_thread_info(self):
info = sys.thread_info info = sys.thread_info

View file

@ -9,6 +9,7 @@ import json
import textwrap import textwrap
from copy import copy from copy import copy
from test import support
from test.support import ( from test.support import (
captured_stdout, captured_stdout,
is_android, is_android,
@ -455,20 +456,20 @@ class TestSysConfig(unittest.TestCase, VirtualEnvironmentMixin):
library = sysconfig.get_config_var('LIBRARY') library = sysconfig.get_config_var('LIBRARY')
ldlibrary = sysconfig.get_config_var('LDLIBRARY') ldlibrary = sysconfig.get_config_var('LDLIBRARY')
major, minor = sys.version_info[:2] major, minor = sys.version_info[:2]
if sys.platform == 'win32': abiflags = sysconfig.get_config_var('ABIFLAGS')
self.assertTrue(library.startswith(f'python{major}{minor}')) if sys.platform.startswith('win'):
self.assertTrue(library.endswith('.dll')) self.assertEqual(library, f'python{major}{minor}{abiflags}.dll')
self.assertEqual(library, ldlibrary) self.assertEqual(library, ldlibrary)
elif is_apple_mobile: elif is_apple_mobile:
framework = sysconfig.get_config_var('PYTHONFRAMEWORK') framework = sysconfig.get_config_var('PYTHONFRAMEWORK')
self.assertEqual(ldlibrary, f"{framework}.framework/{framework}") self.assertEqual(ldlibrary, f"{framework}.framework/{framework}")
else: else:
self.assertTrue(library.startswith(f'libpython{major}.{minor}')) self.assertStartsWith(library, f'libpython{major}.{minor}')
self.assertTrue(library.endswith('.a')) self.assertEndsWith(library, '.a')
if sys.platform == 'darwin' and sys._framework: if sys.platform == 'darwin' and sys._framework:
self.skipTest('gh-110824: skip LDLIBRARY test for framework build') self.skipTest('gh-110824: skip LDLIBRARY test for framework build')
else: else:
self.assertTrue(ldlibrary.startswith(f'libpython{major}.{minor}')) self.assertStartsWith(ldlibrary, f'libpython{major}.{minor}')
@unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX") @unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX")
@requires_subprocess() @requires_subprocess()
@ -592,6 +593,63 @@ class TestSysConfig(unittest.TestCase, VirtualEnvironmentMixin):
suffix = sysconfig.get_config_var('EXT_SUFFIX') suffix = sysconfig.get_config_var('EXT_SUFFIX')
self.assertTrue(suffix.endswith('-darwin.so'), suffix) self.assertTrue(suffix.endswith('-darwin.so'), suffix)
def test_always_set_py_debug(self):
self.assertIn('Py_DEBUG', sysconfig.get_config_vars())
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):
self.assertIn('Py_GIL_DISABLED', sysconfig.get_config_vars())
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):
# 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)
if os.name == 'nt':
self.assertEqual(abiflags, '')
if not sys.platform.startswith('win'):
valid_abiflags = ('', 't', 'd', 'td')
else:
# Windows uses '_d' rather than 'd'; see also test_abi_debug below
valid_abiflags = ('', 't', '_d', 't_d')
self.assertIn(ABIFLAGS, valid_abiflags)
def test_abi_debug(self):
ABIFLAGS = sysconfig.get_config_var('ABIFLAGS')
if support.Py_DEBUG:
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.startswith('win'):
self.assertEndsWith(ABIFLAGS, '_d')
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() @requires_subprocess()
def test_makefile_overwrites_config_vars(self): def test_makefile_overwrites_config_vars(self):
script = textwrap.dedent(""" script = textwrap.dedent("""

View file

@ -1402,6 +1402,7 @@ Todd R. Palmer
Juan David Ibáñez Palomar Juan David Ibáñez Palomar
Nicola Palumbo Nicola Palumbo
Jan Palus Jan Palus
Xuehai Pan
Yongzhi Pan Yongzhi Pan
Martin Panter Martin Panter
Mathias Panzenböck Mathias Panzenböck

View file

@ -0,0 +1 @@
Add ``ABIFLAGS`` to :func:`sysconfig.get_config_vars` on Windows. Patch by Xuehai Pan.

View file

@ -67,6 +67,16 @@ _sysconfig_config_vars_impl(PyObject *module)
return NULL; 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; return config;
} }