gh-88402: Add new sysconfig variables on Windows (GH-110049)

Co-authored-by: Filipe Laíns <filipe.lains@gmail.com>
This commit is contained in:
Sam Gross 2023-10-04 22:50:29 +00:00 committed by GitHub
parent 80dc39e1dc
commit cf6f23b0e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 231 additions and 70 deletions

View File

@ -0,0 +1,57 @@
#ifndef Py_INTERNAL_IMPORTDL_H
#define Py_INTERNAL_IMPORTDL_H
#include "patchlevel.h" // PY_MAJOR_VERSION
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
extern const char *_PyImport_DynLoadFiletab[];
extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *);
typedef PyObject *(*PyModInitFunction)(void);
/* Max length of module suffix searched for -- accommodates "module.slb" */
#define MAXSUFFIXSIZE 12
#ifdef MS_WINDOWS
#include <windows.h>
typedef FARPROC dl_funcptr;
#ifdef _DEBUG
# define PYD_DEBUG_SUFFIX "_d"
#else
# define PYD_DEBUG_SUFFIX ""
#endif
#ifdef Py_NOGIL
# define PYD_THREADING_TAG "t"
#else
# define PYD_THREADING_TAG ""
#endif
#ifdef PYD_PLATFORM_TAG
# define PYD_SOABI "cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) PYD_THREADING_TAG "-" PYD_PLATFORM_TAG
#else
# define PYD_SOABI "cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) PYD_THREADING_TAG
#endif
#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX "." PYD_SOABI ".pyd"
#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd"
#else
typedef void (*dl_funcptr)(void);
#endif
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_IMPORTDL_H */

View File

@ -544,16 +544,20 @@ def _init_posix(vars):
def _init_non_posix(vars): def _init_non_posix(vars):
"""Initialize the module as appropriate for NT""" """Initialize the module as appropriate for NT"""
# set basic install directories # set basic install directories
import _imp import _winapi
import _sysconfig
vars['LIBDEST'] = get_path('stdlib') vars['LIBDEST'] = get_path('stdlib')
vars['BINLIBDEST'] = get_path('platstdlib') vars['BINLIBDEST'] = get_path('platstdlib')
vars['INCLUDEPY'] = get_path('include') vars['INCLUDEPY'] = get_path('include')
try:
# GH-99201: _imp.extension_suffixes may be empty when # Add EXT_SUFFIX, SOABI, and Py_NOGIL
# HAVE_DYNAMIC_LOADING is not set. In this case, don't set EXT_SUFFIX. vars.update(_sysconfig.config_vars())
vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0]
except IndexError: vars['LIBDIR'] = _safe_realpath(os.path.join(get_config_var('installed_base'), 'libs'))
pass if hasattr(sys, 'dllhandle'):
dllhandle = _winapi.GetModuleFileName(sys.dllhandle)
vars['LIBRARY'] = os.path.basename(_safe_realpath(dllhandle))
vars['LDLIBRARY'] = vars['LIBRARY']
vars['EXE'] = '.exe' vars['EXE'] = '.exe'
vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))

View File

@ -17,7 +17,9 @@ from sysconfig import (get_paths, get_platform, get_config_vars,
get_path, get_path_names, _INSTALL_SCHEMES, get_path, get_path_names, _INSTALL_SCHEMES,
get_default_scheme, get_scheme_names, get_config_var, get_default_scheme, get_scheme_names, get_config_var,
_expand_vars, _get_preferred_schemes, _main) _expand_vars, _get_preferred_schemes, _main)
import _imp
import _osx_support import _osx_support
import _sysconfig
HAS_USER_BASE = sysconfig._HAS_USER_BASE HAS_USER_BASE = sysconfig._HAS_USER_BASE
@ -394,6 +396,24 @@ class TestSysConfig(unittest.TestCase):
self.assertIn(ldflags, ldshared) self.assertIn(ldflags, ldshared)
@unittest.skipIf(not _imp.extension_suffixes(), "stub loader has no suffixes")
def test_soabi(self):
soabi = sysconfig.get_config_var('SOABI')
self.assertIn(soabi, _imp.extension_suffixes()[0])
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'))
self.assertEqual(library, ldlibrary)
else:
self.assertTrue(library.startswith(f'libpython{major}.{minor}'))
self.assertTrue(library.endswith('.a'))
self.assertTrue(ldlibrary.startswith(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()
def test_platform_in_subprocess(self): def test_platform_in_subprocess(self):
@ -472,10 +492,8 @@ class TestSysConfig(unittest.TestCase):
@unittest.skipIf(sysconfig.get_config_var('EXT_SUFFIX') is None, @unittest.skipIf(sysconfig.get_config_var('EXT_SUFFIX') is None,
'EXT_SUFFIX required for this test') 'EXT_SUFFIX required for this test')
@unittest.skipIf(not _imp.extension_suffixes(), "stub loader has no suffixes")
def test_EXT_SUFFIX_in_vars(self): def test_EXT_SUFFIX_in_vars(self):
import _imp
if not _imp.extension_suffixes():
self.skipTest("stub loader has no suffixes")
vars = sysconfig.get_config_vars() vars = sysconfig.get_config_vars()
self.assertEqual(vars['EXT_SUFFIX'], _imp.extension_suffixes()[0]) self.assertEqual(vars['EXT_SUFFIX'], _imp.extension_suffixes()[0])

View File

@ -0,0 +1,2 @@
Add new variables to :py:meth:`sysconfig.get_config_vars` on Windows:
``LIBRARY``, ``LDLIBRARY``, ``LIBDIR``, ``SOABI``, and ``Py_NOGIL``.

View File

@ -155,6 +155,7 @@ PYTHONPATH=$(COREPYTHONPATH)
#math mathmodule.c #math mathmodule.c
#mmap mmapmodule.c #mmap mmapmodule.c
#select selectmodule.c #select selectmodule.c
#_sysconfig _sysconfig.c
# XML # XML
#_elementtree _elementtree.c #_elementtree _elementtree.c

View File

@ -19,6 +19,7 @@ errno errnomodule.c
_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c _io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c
itertools itertoolsmodule.c itertools itertoolsmodule.c
_sre _sre/sre.c _sre _sre/sre.c
_sysconfig _sysconfig.c
_thread _threadmodule.c _thread _threadmodule.c
time timemodule.c time timemodule.c
_typing _typingmodule.c _typing _typingmodule.c

98
Modules/_sysconfig.c Normal file
View File

@ -0,0 +1,98 @@
// _sysconfig provides data for the Python sysconfig module
#ifndef Py_BUILD_CORE_BUILTIN
# define Py_BUILD_CORE_MODULE 1
#endif
#include "Python.h"
#include "pycore_importdl.h" // _PyImport_DynLoadFiletab
#include "pycore_long.h" // _PyLong_GetZero, _PyLong_GetOne
/*[clinic input]
module _sysconfig
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=0a7c02d3e212ac97]*/
#include "clinic/_sysconfig.c.h"
#ifdef MS_WINDOWS
static int
add_string_value(PyObject *dict, const char *key, const char *str_value)
{
PyObject *value = PyUnicode_FromString(str_value);
if (value == NULL) {
return -1;
}
int err = PyDict_SetItemString(dict, key, value);
Py_DECREF(value);
return err;
}
#endif
/*[clinic input]
_sysconfig.config_vars
Returns a dictionary containing build variables intended to be exposed by sysconfig.
[clinic start generated code]*/
static PyObject *
_sysconfig_config_vars_impl(PyObject *module)
/*[clinic end generated code: output=9c41cdee63ea9487 input=391ff42f3af57d01]*/
{
PyObject *config = PyDict_New();
if (config == NULL) {
return NULL;
}
#ifdef MS_WINDOWS
if (add_string_value(config, "EXT_SUFFIX", PYD_TAGGED_SUFFIX) < 0) {
Py_DECREF(config);
return NULL;
}
if (add_string_value(config, "SOABI", PYD_SOABI) < 0) {
Py_DECREF(config);
return NULL;
}
#endif
#ifdef Py_NOGIL
PyObject *py_nogil = _PyLong_GetOne();
#else
PyObject *py_nogil = _PyLong_GetZero();
#endif
if (PyDict_SetItemString(config, "Py_NOGIL", py_nogil) < 0) {
Py_DECREF(config);
return NULL;
}
return config;
}
PyDoc_STRVAR(sysconfig__doc__,
"A helper for the sysconfig module.");
static struct PyMethodDef sysconfig_methods[] = {
_SYSCONFIG_CONFIG_VARS_METHODDEF
{NULL, NULL}
};
static PyModuleDef_Slot sysconfig_slots[] = {
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
{0, NULL}
};
static PyModuleDef sysconfig_module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "_sysconfig",
.m_doc = sysconfig__doc__,
.m_methods = sysconfig_methods,
.m_slots = sysconfig_slots,
};
PyMODINIT_FUNC
PyInit__sysconfig(void)
{
return PyModuleDef_Init(&sysconfig_module);
}

22
Modules/clinic/_sysconfig.c.h generated Normal file
View File

@ -0,0 +1,22 @@
/*[clinic input]
preserve
[clinic start generated code]*/
PyDoc_STRVAR(_sysconfig_config_vars__doc__,
"config_vars($module, /)\n"
"--\n"
"\n"
"Returns a dictionary containing build variables intended to be exposed by sysconfig.");
#define _SYSCONFIG_CONFIG_VARS_METHODDEF \
{"config_vars", (PyCFunction)_sysconfig_config_vars, METH_NOARGS, _sysconfig_config_vars__doc__},
static PyObject *
_sysconfig_config_vars_impl(PyObject *module);
static PyObject *
_sysconfig_config_vars(PyObject *module, PyObject *Py_UNUSED(ignored))
{
return _sysconfig_config_vars_impl(module);
}
/*[clinic end generated code: output=25d395cf02eced1f input=a9049054013a1b77]*/

View File

@ -22,6 +22,7 @@ extern PyObject* PyInit__sha1(void);
extern PyObject* PyInit__sha2(void); extern PyObject* PyInit__sha2(void);
extern PyObject* PyInit__sha3(void); extern PyObject* PyInit__sha3(void);
extern PyObject* PyInit__statistics(void); extern PyObject* PyInit__statistics(void);
extern PyObject* PyInit__sysconfig(void);
extern PyObject* PyInit__typing(void); extern PyObject* PyInit__typing(void);
extern PyObject* PyInit__blake2(void); extern PyObject* PyInit__blake2(void);
extern PyObject* PyInit_time(void); extern PyObject* PyInit_time(void);
@ -102,6 +103,7 @@ struct _inittab _PyImport_Inittab[] = {
{"_sha2", PyInit__sha2}, {"_sha2", PyInit__sha2},
{"_sha3", PyInit__sha3}, {"_sha3", PyInit__sha3},
{"_blake2", PyInit__blake2}, {"_blake2", PyInit__blake2},
{"_sysconfig", PyInit__sysconfig},
{"time", PyInit_time}, {"time", PyInit_time},
{"_thread", PyInit__thread}, {"_thread", PyInit__thread},
{"_tokenize", PyInit__tokenize}, {"_tokenize", PyInit__tokenize},

View File

@ -240,6 +240,7 @@
<ClInclude Include="..\Include\internal\pycore_hashtable.h" /> <ClInclude Include="..\Include\internal\pycore_hashtable.h" />
<ClInclude Include="..\Include\internal\pycore_identifier.h" /> <ClInclude Include="..\Include\internal\pycore_identifier.h" />
<ClInclude Include="..\Include\internal\pycore_import.h" /> <ClInclude Include="..\Include\internal\pycore_import.h" />
<ClInclude Include="..\Include\internal\pycore_importdl.h" />
<ClInclude Include="..\Include\internal\pycore_initconfig.h" /> <ClInclude Include="..\Include\internal\pycore_initconfig.h" />
<ClInclude Include="..\Include\internal\pycore_interp.h" /> <ClInclude Include="..\Include\internal\pycore_interp.h" />
<ClInclude Include="..\Include\internal\pycore_intrinsics.h" /> <ClInclude Include="..\Include\internal\pycore_intrinsics.h" />
@ -367,7 +368,6 @@
<ClInclude Include="..\PC\errmap.h" /> <ClInclude Include="..\PC\errmap.h" />
<ClInclude Include="..\PC\pyconfig.h" /> <ClInclude Include="..\PC\pyconfig.h" />
<ClInclude Include="..\Python\condvar.h" /> <ClInclude Include="..\Python\condvar.h" />
<ClInclude Include="..\Python\importdl.h" />
<ClInclude Include="..\Python\stdlib_module_names.h" /> <ClInclude Include="..\Python\stdlib_module_names.h" />
<ClInclude Include="..\Python\thread_nt.h" /> <ClInclude Include="..\Python\thread_nt.h" />
</ItemGroup> </ItemGroup>
@ -438,6 +438,7 @@
<ClCompile Include="..\Modules\signalmodule.c" /> <ClCompile Include="..\Modules\signalmodule.c" />
<ClCompile Include="..\Modules\_statisticsmodule.c" /> <ClCompile Include="..\Modules\_statisticsmodule.c" />
<ClCompile Include="..\Modules\symtablemodule.c" /> <ClCompile Include="..\Modules\symtablemodule.c" />
<ClCompile Include="..\Modules\_sysconfig.c" />
<ClCompile Include="..\Modules\_threadmodule.c" /> <ClCompile Include="..\Modules\_threadmodule.c" />
<ClCompile Include="..\Modules\_tracemalloc.c" /> <ClCompile Include="..\Modules\_tracemalloc.c" />
<ClCompile Include="..\Modules\_typingmodule.c" /> <ClCompile Include="..\Modules\_typingmodule.c" />

View File

@ -300,9 +300,6 @@
<ClInclude Include="..\PC\pyconfig.h"> <ClInclude Include="..\PC\pyconfig.h">
<Filter>PC</Filter> <Filter>PC</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Python\importdl.h">
<Filter>Python</Filter>
</ClInclude>
<ClInclude Include="..\Python\stdlib_module_names.h"> <ClInclude Include="..\Python\stdlib_module_names.h">
<Filter>Python</Filter> <Filter>Python</Filter>
</ClInclude> </ClInclude>
@ -633,6 +630,9 @@
<ClInclude Include="..\Include\internal\pycore_import.h"> <ClInclude Include="..\Include\internal\pycore_import.h">
<Filter>Include\internal</Filter> <Filter>Include\internal</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\internal\pycore_importdl.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_initconfig.h"> <ClInclude Include="..\Include\internal\pycore_initconfig.h">
<Filter>Include\internal</Filter> <Filter>Include\internal</Filter>
</ClInclude> </ClInclude>
@ -959,6 +959,9 @@
<ClCompile Include="..\Modules\symtablemodule.c"> <ClCompile Include="..\Modules\symtablemodule.c">
<Filter>Modules</Filter> <Filter>Modules</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\Modules\_sysconfig.c">
<Filter>Modules</Filter>
</ClCompile>
<ClCompile Include="..\Modules\_threadmodule.c"> <ClCompile Include="..\Modules\_threadmodule.c">
<Filter>Modules</Filter> <Filter>Modules</Filter>
</ClCompile> </ClCompile>

View File

@ -5,7 +5,7 @@
#include <errno.h> #include <errno.h>
#include "Python.h" #include "Python.h"
#include "importdl.h" #include "pycore_importdl.h"
#if defined(__hp9000s300) #if defined(__hp9000s300)
#define FUNCNAME_PATTERN "_%.20s_%.200s" #define FUNCNAME_PATTERN "_%.20s_%.200s"

View File

@ -4,7 +4,7 @@
#include "Python.h" #include "Python.h"
#include "pycore_interp.h" // _PyInterpreterState.dlopenflags #include "pycore_interp.h" // _PyInterpreterState.dlopenflags
#include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "importdl.h" #include "pycore_importdl.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>

View File

@ -3,7 +3,7 @@
not present. */ not present. */
#include "Python.h" #include "Python.h"
#include "importdl.h" #include "pycore_importdl.h"
const char *_PyImport_DynLoadFiletab[] = {NULL}; const char *_PyImport_DynLoadFiletab[] = {NULL};

View File

@ -5,30 +5,10 @@
#include "pycore_fileutils.h" // _Py_add_relfile() #include "pycore_fileutils.h" // _Py_add_relfile()
#include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "importdl.h" // dl_funcptr #include "pycore_importdl.h" // dl_funcptr
#include "patchlevel.h" // PY_MAJOR_VERSION #include "patchlevel.h" // PY_MAJOR_VERSION
#include <windows.h> #include <windows.h>
#ifdef _DEBUG
#define PYD_DEBUG_SUFFIX "_d"
#else
#define PYD_DEBUG_SUFFIX ""
#endif
#ifdef Py_NOGIL
# define PYD_THREADING_TAG "t"
#else
# define PYD_THREADING_TAG ""
#endif
#ifdef PYD_PLATFORM_TAG
#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) PYD_THREADING_TAG "-" PYD_PLATFORM_TAG ".pyd"
#else
#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) PYD_THREADING_TAG ".pyd"
#endif
#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd"
const char *_PyImport_DynLoadFiletab[] = { const char *_PyImport_DynLoadFiletab[] = {
PYD_TAGGED_SUFFIX, PYD_TAGGED_SUFFIX,
PYD_UNTAGGED_SUFFIX, PYD_UNTAGGED_SUFFIX,

View File

@ -17,7 +17,7 @@
#include "pycore_weakref.h" // _PyWeakref_GET_REF() #include "pycore_weakref.h" // _PyWeakref_GET_REF()
#include "marshal.h" // PyMarshal_ReadObjectFromString() #include "marshal.h" // PyMarshal_ReadObjectFromString()
#include "importdl.h" // _PyImport_DynLoadFiletab #include "pycore_importdl.h" // _PyImport_DynLoadFiletab
#include "pydtrace.h" // PyDTrace_IMPORT_FIND_LOAD_START_ENABLED() #include "pydtrace.h" // PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()
#include <stdbool.h> // bool #include <stdbool.h> // bool

View File

@ -15,7 +15,7 @@
*/ */
#ifdef HAVE_DYNAMIC_LOADING #ifdef HAVE_DYNAMIC_LOADING
#include "importdl.h" #include "pycore_importdl.h"
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
extern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, extern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,

View File

@ -1,29 +0,0 @@
#ifndef Py_IMPORTDL_H
#define Py_IMPORTDL_H
#ifdef __cplusplus
extern "C" {
#endif
extern const char *_PyImport_DynLoadFiletab[];
extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *);
typedef PyObject *(*PyModInitFunction)(void);
/* Max length of module suffix searched for -- accommodates "module.slb" */
#define MAXSUFFIXSIZE 12
#ifdef MS_WINDOWS
#include <windows.h>
typedef FARPROC dl_funcptr;
#else
typedef void (*dl_funcptr)(void);
#endif
#ifdef __cplusplus
}
#endif
#endif /* !Py_IMPORTDL_H */

View File

@ -77,6 +77,7 @@ static const char* _Py_stdlib_module_names[] = {
"_strptime", "_strptime",
"_struct", "_struct",
"_symtable", "_symtable",
"_sysconfig",
"_thread", "_thread",
"_threading_local", "_threading_local",
"_tkinter", "_tkinter",

View File

@ -607,6 +607,7 @@ Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput AST_LITERAL_EVAL_INITIALIZED
# XXX Fix the analyzer. # XXX Fix the analyzer.
## forward/extern references ## forward/extern references
Include/internal/pycore_importdl.h - _PyImport_DynLoadFiletab -
Include/py_curses.h - PyCurses_API - Include/py_curses.h - PyCurses_API -
Include/pydecimal.h - _decimal_api - Include/pydecimal.h - _decimal_api -
Modules/_blake2/blake2module.c - blake2b_type_spec - Modules/_blake2/blake2module.c - blake2b_type_spec -
@ -668,7 +669,6 @@ Objects/object.c - _PyLineIterator -
Objects/object.c - _PyPositionsIterator - Objects/object.c - _PyPositionsIterator -
Python/perf_trampoline.c - _Py_trampoline_func_start - Python/perf_trampoline.c - _Py_trampoline_func_start -
Python/perf_trampoline.c - _Py_trampoline_func_end - Python/perf_trampoline.c - _Py_trampoline_func_end -
Python/importdl.h - _PyImport_DynLoadFiletab -
Modules/expat/xmlrole.c - prolog0 - Modules/expat/xmlrole.c - prolog0 -
Modules/expat/xmlrole.c - prolog1 - Modules/expat/xmlrole.c - prolog1 -
Modules/expat/xmlrole.c - prolog2 - Modules/expat/xmlrole.c - prolog2 -

Can't render this file because it has a wrong number of fields in line 4.