From 01de89cb59107d4f889aa503a1c0350dae4aebaf Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 14 Nov 2018 17:39:45 +0100 Subject: [PATCH] bpo-35233: InitConfigTests tests more config vars (GH-10541) test_embed.InitConfigTests tests more configuration variables. Changes: * InitConfigTests tests more core configuration variables: * base_exec_prefix * base_prefix * exec_prefix * home * legacy_windows_fs_encoding * legacy_windows_stdio * module_search_path_env * prefix * "_testembed init_from_config" tests more variables: * argv * warnoptions * xoptions * InitConfigTests: add check_global_config(), check_core_config() and check_main_config() subfunctions to cleanup the code. Move also constants at the class level (ex: COPY_MAIN_CONFIG). * Fix _PyCoreConfig_AsDict(): don't set stdio_encoding twice * Use more macros in _PyCoreConfig_AsDict() and _PyMainInterpreterConfig_AsDict() to reduce code duplication. * Other minor cleanups. --- Include/coreconfig.h | 4 +- Include/pylifecycle.h | 1 + Lib/test/test_embed.py | 211 +++++++++++++++++++++++++---------------- Modules/main.c | 74 ++++++++------- Programs/_testembed.c | 32 ++++++- Python/coreconfig.c | 191 +++++++++++++++---------------------- 6 files changed, 274 insertions(+), 239 deletions(-) diff --git a/Include/coreconfig.h b/Include/coreconfig.h index f71a364cc2..0ed3222a15 100644 --- a/Include/coreconfig.h +++ b/Include/coreconfig.h @@ -359,9 +359,9 @@ PyAPI_FUNC(int) _PyCoreConfig_GetEnvDup( wchar_t *wname, char *name); -/* Used by _testcapi.get_coreconfig() */ -PyAPI_FUNC(PyObject *) _PyCoreConfig_AsDict(const _PyCoreConfig *config); +/* Used by _testcapi.get_global_config() and _testcapi.get_core_config() */ PyAPI_FUNC(PyObject *) _Py_GetGlobalVariablesAsDict(void); +PyAPI_FUNC(PyObject *) _PyCoreConfig_AsDict(const _PyCoreConfig *config); #endif #ifdef __cplusplus diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h index 3d9365d315..7d383aa089 100644 --- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -37,6 +37,7 @@ PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *); PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy( _PyMainInterpreterConfig *config, const _PyMainInterpreterConfig *config2); +/* Used by _testcapi.get_main_config() */ PyAPI_FUNC(PyObject*) _PyMainInterpreterConfig_AsDict( const _PyMainInterpreterConfig *config); diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 03a11842fa..75e31c2111 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -11,12 +11,15 @@ import subprocess import sys +MS_WINDOWS = (os.name == 'nt') + + class EmbeddingTestsMixin: def setUp(self): here = os.path.abspath(__file__) basepath = os.path.dirname(os.path.dirname(os.path.dirname(here))) exename = "_testembed" - if sys.platform.startswith("win"): + if MS_WINDOWS: ext = ("_d" if "_d" in sys.executable else "") + ".exe" exename += ext exepath = os.path.dirname(sys.executable) @@ -38,7 +41,7 @@ class EmbeddingTestsMixin: """Runs a test in the embedded interpreter""" cmd = [self.test_exe] cmd.extend(args) - if env is not None and sys.platform == 'win32': + if env is not None and MS_WINDOWS: # Windows requires at least the SYSTEMROOT environment variable to # start Python. env = env.copy() @@ -199,7 +202,7 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): """ env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path)) out, err = self.run_embedded_interpreter("pre_initialization_api", env=env) - if sys.platform == "win32": + if MS_WINDOWS: expected_path = self.test_exe else: expected_path = os.path.join(os.getcwd(), "spam") @@ -253,25 +256,14 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): maxDiff = 4096 - UTF8_MODE_ERRORS = ('surrogatepass' if sys.platform == 'win32' - else 'surrogateescape') - # FIXME: untested core configuration variables + UTF8_MODE_ERRORS = ('surrogatepass' if MS_WINDOWS else 'surrogateescape') + + # core config UNTESTED_CORE_CONFIG = ( - 'base_exec_prefix', - 'base_prefix', + # FIXME: untested core configuration variables 'dll_path', - 'exec_prefix', 'executable', - 'home', - 'legacy_windows_fs_encoding', - 'legacy_windows_stdio', - 'module_search_path_env', 'module_search_paths', - 'prefix', - ) - # FIXME: untested main configuration variables - UNTESTED_MAIN_CONFIG = ( - 'module_search_path', ) DEFAULT_CORE_CONFIG = { 'install_signal_handlers': 1, @@ -304,6 +296,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'xoptions': [], 'warnoptions': [], + 'module_search_path_env': None, + 'home': None, + 'prefix': sys.prefix, + 'base_prefix': sys.base_prefix, + 'exec_prefix': sys.exec_prefix, + 'base_exec_prefix': sys.base_exec_prefix, + 'isolated': 0, 'site_import': 1, 'bytes_warning': 0, @@ -325,6 +324,63 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): '_check_hash_pycs_mode': 'default', '_frozen': 0, } + if MS_WINDOWS: + DEFAULT_CORE_CONFIG.update({ + 'legacy_windows_fs_encoding': 0, + 'legacy_windows_stdio': 0, + }) + + # main config + UNTESTED_MAIN_CONFIG = ( + # FIXME: untested main configuration variables + 'module_search_path', + ) + COPY_MAIN_CONFIG = ( + # Copy core config to main config for expected values + 'argv', + 'base_exec_prefix', + 'base_prefix', + 'exec_prefix', + 'executable', + 'install_signal_handlers', + 'prefix', + 'pycache_prefix', + 'warnoptions', + # xoptions is created from core_config in check_main_config() + ) + + # global config + DEFAULT_GLOBAL_CONFIG = { + 'Py_HasFileSystemDefaultEncoding': 0, + 'Py_HashRandomizationFlag': 1, + '_Py_HasFileSystemDefaultEncodeErrors': 0, + } + COPY_GLOBAL_CONFIG = [ + # Copy core config to global config for expected values + # True means that the core config value is inverted (0 => 1 and 1 => 0) + ('Py_BytesWarningFlag', 'bytes_warning'), + ('Py_DebugFlag', 'parser_debug'), + ('Py_DontWriteBytecodeFlag', 'write_bytecode', True), + ('Py_FileSystemDefaultEncodeErrors', 'filesystem_errors'), + ('Py_FileSystemDefaultEncoding', 'filesystem_encoding'), + ('Py_FrozenFlag', '_frozen'), + ('Py_IgnoreEnvironmentFlag', 'use_environment', True), + ('Py_InspectFlag', 'inspect'), + ('Py_InteractiveFlag', 'interactive'), + ('Py_IsolatedFlag', 'isolated'), + ('Py_NoSiteFlag', 'site_import', True), + ('Py_NoUserSiteDirectory', 'user_site_directory', True), + ('Py_OptimizeFlag', 'optimization_level'), + ('Py_QuietFlag', 'quiet'), + ('Py_UTF8Mode', 'utf8_mode'), + ('Py_UnbufferedStdioFlag', 'buffered_stdio', True), + ('Py_VerboseFlag', 'verbose'), + ] + if MS_WINDOWS: + COPY_GLOBAL_CONFIG.extend(( + ('Py_LegacyWindowsFSEncodingFlag', 'legacy_windows_fs_encoding'), + ('Py_LegacyWindowsStdioFlag', 'legacy_windows_stdio'), + )) def get_stdio_encoding(self, env): code = 'import sys; print(sys.stdout.encoding, sys.stdout.errors)' @@ -355,18 +411,31 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): out = proc.stdout.rstrip() return out.split() - def check_config(self, testname, expected): - expected = dict(self.DEFAULT_CORE_CONFIG, **expected) + def main_xoptions(self, xoptions_list): + xoptions = {} + for opt in xoptions_list: + if '=' in opt: + key, value = opt.split('=', 1) + xoptions[key] = value + else: + xoptions[opt] = True + return xoptions - env = dict(os.environ) - for key in list(env): - if key.startswith('PYTHON'): - del env[key] - # Disable C locale coercion and UTF-8 mode to not depend - # on the current locale - env['PYTHONCOERCECLOCALE'] = '0' - env['PYTHONUTF8'] = '0' + def check_main_config(self, config): + core_config = config['core_config'] + main_config = config['main_config'] + + # main config + for key in self.UNTESTED_MAIN_CONFIG: + del main_config[key] + expected_main = {} + for key in self.COPY_MAIN_CONFIG: + expected_main[key] = core_config[key] + expected_main['xoptions'] = self.main_xoptions(core_config['xoptions']) + self.assertEqual(main_config, expected_main) + + def check_core_config(self, config, expected, env): if expected['stdio_encoding'] is None or expected['stdio_errors'] is None: res = self.get_stdio_encoding(env) if expected['stdio_encoding'] is None: @@ -380,59 +449,16 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): if expected['filesystem_errors'] is None: expected['filesystem_errors'] = res[1] - out, err = self.run_embedded_interpreter(testname, env=env) - # Ignore err + core_config = dict(config['core_config']) + for key in self.UNTESTED_CORE_CONFIG: + core_config.pop(key, None) + self.assertEqual(core_config, expected) - config = json.loads(out) + def check_global_config(self, config): core_config = config['core_config'] - executable = core_config['executable'] - main_config = config['main_config'] - for key in self.UNTESTED_MAIN_CONFIG: - del main_config[key] - - expected_main = { - 'install_signal_handlers': core_config['install_signal_handlers'], - 'argv': [], - 'prefix': sys.prefix, - 'executable': core_config['executable'], - 'base_prefix': sys.base_prefix, - 'base_exec_prefix': sys.base_exec_prefix, - 'warnoptions': core_config['warnoptions'], - 'xoptions': {}, - 'pycache_prefix': core_config['pycache_prefix'], - 'exec_prefix': core_config['exec_prefix'], - } - self.assertEqual(main_config, expected_main) - - - copy_global_config = [ - ('Py_BytesWarningFlag', 'bytes_warning'), - ('Py_DebugFlag', 'parser_debug'), - ('Py_DontWriteBytecodeFlag', 'write_bytecode', True), - ('Py_FileSystemDefaultEncodeErrors', 'filesystem_errors'), - ('Py_FileSystemDefaultEncoding', 'filesystem_encoding'), - ('Py_FrozenFlag', '_frozen'), - ('Py_IgnoreEnvironmentFlag', 'use_environment', True), - ('Py_InspectFlag', 'inspect'), - ('Py_InteractiveFlag', 'interactive'), - ('Py_IsolatedFlag', 'isolated'), - ('Py_NoSiteFlag', 'site_import', True), - ('Py_NoUserSiteDirectory', 'user_site_directory', True), - ('Py_OptimizeFlag', 'optimization_level'), - ('Py_QuietFlag', 'quiet'), - ('Py_UTF8Mode', 'utf8_mode'), - ('Py_UnbufferedStdioFlag', 'buffered_stdio', True), - ('Py_VerboseFlag', 'verbose'), - ] - if os.name == 'nt': - copy_global_config.extend(( - ('Py_LegacyWindowsFSEncodingFlag', 'legacy_windows_fs_encoding'), - ('Py_LegacyWindowsStdioFlag', 'legacy_windows_stdio'), - )) - - expected_global = {} - for item in copy_global_config: + expected_global = dict(self.DEFAULT_GLOBAL_CONFIG) + for item in self.COPY_GLOBAL_CONFIG: if len(item) == 3: global_key, core_key, opposite = item expected_global[global_key] = 0 if core_config[core_key] else 1 @@ -440,14 +466,28 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): global_key, core_key = item expected_global[global_key] = core_config[core_key] - expected_global['Py_HasFileSystemDefaultEncoding'] = 0 - expected_global['_Py_HasFileSystemDefaultEncodeErrors'] = 0 - expected_global['Py_HashRandomizationFlag'] = 1 self.assertEqual(config['global_config'], expected_global) - for key in self.UNTESTED_CORE_CONFIG: - core_config.pop(key, None) - self.assertEqual(core_config, expected) + def check_config(self, testname, expected): + expected = dict(self.DEFAULT_CORE_CONFIG, **expected) + + env = dict(os.environ) + # Remove PYTHON* environment variables to get deterministic environment + for key in list(env): + if key.startswith('PYTHON'): + del env[key] + # Disable C locale coercion and UTF-8 mode to not depend + # on the current locale + env['PYTHONCOERCECLOCALE'] = '0' + env['PYTHONUTF8'] = '0' + + out, err = self.run_embedded_interpreter(testname, env=env) + # Ignore err + config = json.loads(out) + + self.check_core_config(config, expected, env) + self.check_main_config(config) + self.check_global_config(config) def test_init_default_config(self): self.check_config("init_default_config", {}) @@ -495,7 +535,10 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'pycache_prefix': 'conf_pycache_prefix', 'program_name': './conf_program_name', + 'argv': ['-c', 'pass'], 'program': 'conf_program', + 'xoptions': ['core_xoption1=3', 'core_xoption2=', 'core_xoption3'], + 'warnoptions': ['default', 'error::ResourceWarning'], 'site_import': 0, 'bytes_warning': 1, diff --git a/Modules/main.c b/Modules/main.c index 3e51ef8e0b..8e66ddded4 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -1442,11 +1442,11 @@ _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config, _PyMainInterpreterConfig_Clear(config); #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR -#define COPY_OBJ_ATTR(OBJ_ATTR) \ +#define COPY_OBJ_ATTR(ATTR) \ do { \ - if (config2->OBJ_ATTR != NULL) { \ - config->OBJ_ATTR = config_copy_attr(config2->OBJ_ATTR); \ - if (config->OBJ_ATTR == NULL) { \ + if (config2->ATTR != NULL) { \ + config->ATTR = config_copy_attr(config2->ATTR); \ + if (config->ATTR == NULL) { \ return -1; \ } \ } \ @@ -1480,38 +1480,42 @@ _PyMainInterpreterConfig_AsDict(const _PyMainInterpreterConfig *config) return NULL; } -#define SET_ITEM(KEY, ATTR) \ - do { \ - obj = config->ATTR; \ - if (obj == NULL) { \ - obj = Py_None; \ - } \ - res = PyDict_SetItemString(dict, (KEY), obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) +#define SET_ITEM_INT(ATTR) \ + do { \ + obj = PyLong_FromLong(config->ATTR); \ + if (obj == NULL) { \ + goto fail; \ + } \ + res = PyDict_SetItemString(dict, #ATTR, obj); \ + Py_DECREF(obj); \ + if (res < 0) { \ + goto fail; \ + } \ + } while (0) - obj = PyLong_FromLong(config->install_signal_handlers); - if (obj == NULL) { - goto fail; - } - res = PyDict_SetItemString(dict, "install_signal_handlers", obj); - Py_DECREF(obj); - if (res < 0) { - goto fail; - } +#define SET_ITEM_OBJ(ATTR) \ + do { \ + obj = config->ATTR; \ + if (obj == NULL) { \ + obj = Py_None; \ + } \ + res = PyDict_SetItemString(dict, #ATTR, obj); \ + if (res < 0) { \ + goto fail; \ + } \ + } while (0) - SET_ITEM("argv", argv); - SET_ITEM("executable", executable); - SET_ITEM("prefix", prefix); - SET_ITEM("base_prefix", base_prefix); - SET_ITEM("exec_prefix", exec_prefix); - SET_ITEM("base_exec_prefix", base_exec_prefix); - SET_ITEM("warnoptions", warnoptions); - SET_ITEM("xoptions", xoptions); - SET_ITEM("module_search_path", module_search_path); - SET_ITEM("pycache_prefix", pycache_prefix); + SET_ITEM_INT(install_signal_handlers); + SET_ITEM_OBJ(argv); + SET_ITEM_OBJ(executable); + SET_ITEM_OBJ(prefix); + SET_ITEM_OBJ(base_prefix); + SET_ITEM_OBJ(exec_prefix); + SET_ITEM_OBJ(base_exec_prefix); + SET_ITEM_OBJ(warnoptions); + SET_ITEM_OBJ(xoptions); + SET_ITEM_OBJ(module_search_path); + SET_ITEM_OBJ(pycache_prefix); return dict; @@ -1519,7 +1523,7 @@ fail: Py_DECREF(dict); return NULL; -#undef SET_ITEM +#undef SET_ITEM_OBJ } diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 12dc0f98be..22212bff52 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -355,6 +355,7 @@ error: return -1; } + static void dump_config(void) { @@ -468,10 +469,30 @@ static int test_init_from_config(void) Py_SetProgramName(L"./globalvar"); config.program_name = L"./conf_program_name"; - /* FIXME: test argc/argv */ + static wchar_t* argv[2] = { + L"-c", + L"pass", + }; + config.argc = Py_ARRAY_LENGTH(argv); + config.argv = argv; + config.program = L"conf_program"; - /* FIXME: test xoptions */ - /* FIXME: test warnoptions */ + + static wchar_t* xoptions[3] = { + L"core_xoption1=3", + L"core_xoption2=", + L"core_xoption3", + }; + config.nxoption = Py_ARRAY_LENGTH(xoptions); + config.xoptions = xoptions; + + static wchar_t* warnoptions[2] = { + L"default", + L"error::ResourceWarning", + }; + config.nwarnoption = Py_ARRAY_LENGTH(warnoptions); + config.warnoptions = warnoptions; + /* FIXME: test module_search_path_env */ /* FIXME: test home */ /* FIXME: test path config: module_search_path .. dll_path */ @@ -512,6 +533,11 @@ static int test_init_from_config(void) putenv("PYTHONIOENCODING=cp424"); Py_SetStandardStreamEncoding("ascii", "ignore"); +#ifdef MS_WINDOWS + /* Py_SetStandardStreamEncoding() sets Py_LegacyWindowsStdioFlag to 1. + Force it to 0 through the config. */ + config.legacy_windows_stdio = 0; +#endif config.stdio_encoding = "iso8859-1"; config.stdio_errors = "replace"; diff --git a/Python/coreconfig.c b/Python/coreconfig.c index 3e547c53ab..a040a865ae 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -1444,14 +1444,6 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) return NULL; } -#define FROM_STRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromString(STR) \ - : (Py_INCREF(Py_None), Py_None)) -#define FROM_WSTRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromWideChar(STR, -1) \ - : (Py_INCREF(Py_None), Py_None)) #define SET_ITEM(KEY, EXPR) \ do { \ obj = (EXPR); \ @@ -1464,117 +1456,81 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) goto fail; \ } \ } while (0) - - SET_ITEM("install_signal_handlers", - PyLong_FromLong(config->install_signal_handlers)); - SET_ITEM("use_environment", - PyLong_FromLong(config->use_environment)); - SET_ITEM("use_hash_seed", - PyLong_FromLong(config->use_hash_seed)); - SET_ITEM("hash_seed", - PyLong_FromUnsignedLong(config->hash_seed)); - SET_ITEM("allocator", - FROM_STRING(config->allocator)); - SET_ITEM("dev_mode", - PyLong_FromLong(config->dev_mode)); - SET_ITEM("faulthandler", - PyLong_FromLong(config->faulthandler)); - SET_ITEM("tracemalloc", - PyLong_FromLong(config->tracemalloc)); - SET_ITEM("import_time", - PyLong_FromLong(config->import_time)); - SET_ITEM("show_ref_count", - PyLong_FromLong(config->show_ref_count)); - SET_ITEM("show_alloc_count", - PyLong_FromLong(config->show_alloc_count)); - SET_ITEM("dump_refs", - PyLong_FromLong(config->dump_refs)); - SET_ITEM("malloc_stats", - PyLong_FromLong(config->malloc_stats)); - SET_ITEM("coerce_c_locale", - PyLong_FromLong(config->coerce_c_locale)); - SET_ITEM("coerce_c_locale_warn", - PyLong_FromLong(config->coerce_c_locale_warn)); - SET_ITEM("filesystem_encoding", - FROM_STRING(config->filesystem_encoding)); - SET_ITEM("filesystem_errors", - FROM_STRING(config->filesystem_errors)); - SET_ITEM("stdio_encoding", - FROM_STRING(config->stdio_encoding)); - SET_ITEM("utf8_mode", - PyLong_FromLong(config->utf8_mode)); - SET_ITEM("pycache_prefix", - FROM_WSTRING(config->pycache_prefix)); - SET_ITEM("program_name", - FROM_WSTRING(config->program_name)); - SET_ITEM("argv", - _Py_wstrlist_as_pylist(config->argc, config->argv)); - SET_ITEM("program", - FROM_WSTRING(config->program)); - SET_ITEM("xoptions", - _Py_wstrlist_as_pylist(config->nxoption, config->xoptions)); - SET_ITEM("warnoptions", - _Py_wstrlist_as_pylist(config->nwarnoption, config->warnoptions)); - SET_ITEM("module_search_path_env", - FROM_WSTRING(config->module_search_path_env)); - SET_ITEM("home", - FROM_WSTRING(config->home)); - SET_ITEM("module_search_paths", - _Py_wstrlist_as_pylist(config->nmodule_search_path, config->module_search_paths)); - SET_ITEM("executable", - FROM_WSTRING(config->executable)); - SET_ITEM("prefix", - FROM_WSTRING(config->prefix)); - SET_ITEM("base_prefix", - FROM_WSTRING(config->base_prefix)); - SET_ITEM("exec_prefix", - FROM_WSTRING(config->exec_prefix)); - SET_ITEM("base_exec_prefix", - FROM_WSTRING(config->base_exec_prefix)); +#define FROM_STRING(STR) \ + ((STR != NULL) ? \ + PyUnicode_FromString(STR) \ + : (Py_INCREF(Py_None), Py_None)) +#define SET_ITEM_INT(ATTR) \ + SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) +#define SET_ITEM_UINT(ATTR) \ + SET_ITEM(#ATTR, PyLong_FromUnsignedLong(config->ATTR)) +#define SET_ITEM_STR(ATTR) \ + SET_ITEM(#ATTR, FROM_STRING(config->ATTR)) +#define FROM_WSTRING(STR) \ + ((STR != NULL) ? \ + PyUnicode_FromWideChar(STR, -1) \ + : (Py_INCREF(Py_None), Py_None)) +#define SET_ITEM_WSTR(ATTR) \ + SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) +#define SET_ITEM_WSTRLIST(NOPTION, OPTIONS) \ + SET_ITEM(#OPTIONS, _Py_wstrlist_as_pylist(config->NOPTION, config->OPTIONS)) + + SET_ITEM_INT(install_signal_handlers); + SET_ITEM_INT(use_environment); + SET_ITEM_INT(use_hash_seed); + SET_ITEM_UINT(hash_seed); + SET_ITEM_STR(allocator); + SET_ITEM_INT(dev_mode); + SET_ITEM_INT(faulthandler); + SET_ITEM_INT(tracemalloc); + SET_ITEM_INT(import_time); + SET_ITEM_INT(show_ref_count); + SET_ITEM_INT(show_alloc_count); + SET_ITEM_INT(dump_refs); + SET_ITEM_INT(malloc_stats); + SET_ITEM_INT(coerce_c_locale); + SET_ITEM_INT(coerce_c_locale_warn); + SET_ITEM_STR(filesystem_encoding); + SET_ITEM_STR(filesystem_errors); + SET_ITEM_INT(utf8_mode); + SET_ITEM_WSTR(pycache_prefix); + SET_ITEM_WSTR(program_name); + SET_ITEM_WSTRLIST(argc, argv); + SET_ITEM_WSTR(program); + SET_ITEM_WSTRLIST(nxoption, xoptions); + SET_ITEM_WSTRLIST(nwarnoption, warnoptions); + SET_ITEM_WSTR(module_search_path_env); + SET_ITEM_WSTR(home); + SET_ITEM_WSTRLIST(nmodule_search_path, module_search_paths); + SET_ITEM_WSTR(executable); + SET_ITEM_WSTR(prefix); + SET_ITEM_WSTR(base_prefix); + SET_ITEM_WSTR(exec_prefix); + SET_ITEM_WSTR(base_exec_prefix); #ifdef MS_WINDOWS - SET_ITEM("dll_path", - FROM_WSTRING(config->dll_path)); + SET_ITEM_WSTR(dll_path); #endif - SET_ITEM("isolated", - PyLong_FromLong(config->isolated)); - SET_ITEM("site_import", - PyLong_FromLong(config->site_import)); - SET_ITEM("bytes_warning", - PyLong_FromLong(config->bytes_warning)); - SET_ITEM("inspect", - PyLong_FromLong(config->inspect)); - SET_ITEM("interactive", - PyLong_FromLong(config->interactive)); - SET_ITEM("optimization_level", - PyLong_FromLong(config->optimization_level)); - SET_ITEM("parser_debug", - PyLong_FromLong(config->parser_debug)); - SET_ITEM("write_bytecode", - PyLong_FromLong(config->write_bytecode)); - SET_ITEM("verbose", - PyLong_FromLong(config->verbose)); - SET_ITEM("quiet", - PyLong_FromLong(config->quiet)); - SET_ITEM("user_site_directory", - PyLong_FromLong(config->user_site_directory)); - SET_ITEM("buffered_stdio", - PyLong_FromLong(config->buffered_stdio)); - SET_ITEM("stdio_encoding", - FROM_STRING(config->stdio_encoding)); - SET_ITEM("stdio_errors", - FROM_STRING(config->stdio_errors)); + SET_ITEM_INT(isolated); + SET_ITEM_INT(site_import); + SET_ITEM_INT(bytes_warning); + SET_ITEM_INT(inspect); + SET_ITEM_INT(interactive); + SET_ITEM_INT(optimization_level); + SET_ITEM_INT(parser_debug); + SET_ITEM_INT(write_bytecode); + SET_ITEM_INT(verbose); + SET_ITEM_INT(quiet); + SET_ITEM_INT(user_site_directory); + SET_ITEM_INT(buffered_stdio); + SET_ITEM_STR(stdio_encoding); + SET_ITEM_STR(stdio_errors); #ifdef MS_WINDOWS - SET_ITEM("legacy_windows_fs_encoding", - PyLong_FromLong(config->legacy_windows_fs_encoding)); - SET_ITEM("legacy_windows_stdio", - PyLong_FromLong(config->legacy_windows_stdio)); + SET_ITEM_INT(legacy_windows_fs_encoding); + SET_ITEM_INT(legacy_windows_stdio); #endif - SET_ITEM("_install_importlib", - PyLong_FromLong(config->_install_importlib)); - SET_ITEM("_check_hash_pycs_mode", - FROM_STRING(config->_check_hash_pycs_mode)); - SET_ITEM("_frozen", - PyLong_FromLong(config->_frozen)); + SET_ITEM_INT(_install_importlib); + SET_ITEM_STR(_check_hash_pycs_mode); + SET_ITEM_INT(_frozen); return dict; @@ -1585,4 +1541,9 @@ fail: #undef FROM_STRING #undef FROM_WSTRING #undef SET_ITEM +#undef SET_ITEM_INT +#undef SET_ITEM_UINT +#undef SET_ITEM_STR +#undef SET_ITEM_WSTR +#undef SET_ITEM_WSTRLIST } -- 2.40.0