Skip to content

bpo-36763: Add test for _PyCoreConfig_SetString() #13275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 35 additions & 7 deletions Lib/test/test_embed.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
UNTESTED_CORE_CONFIG = (
# FIXME: untested core configuration variables
'dll_path',
'executable',
'module_search_paths',
)
# Mark config which should be get by get_default_config()
Expand Down Expand Up @@ -310,7 +309,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'filesystem_errors': GET_DEFAULT_CONFIG,

'pycache_prefix': None,
'program_name': './_testembed',
'program_name': GET_DEFAULT_CONFIG,
'argv': [""],
'program': '',

Expand All @@ -319,6 +318,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):

'module_search_path_env': None,
'home': None,
'executable': GET_DEFAULT_CONFIG,

'prefix': GET_DEFAULT_CONFIG,
'base_prefix': GET_DEFAULT_CONFIG,
Expand Down Expand Up @@ -404,7 +404,7 @@ def main_xoptions(self, xoptions_list):
xoptions[opt] = True
return xoptions

def get_expected_config(self, expected, env):
def get_expected_config(self, expected, env, add_path=None):
expected = dict(self.DEFAULT_CORE_CONFIG, **expected)

code = textwrap.dedent('''
Expand All @@ -420,6 +420,7 @@ def get_expected_config(self, expected, env):
'base_exec_prefix': sys.base_exec_prefix,
'filesystem_encoding': sys.getfilesystemencoding(),
'filesystem_errors': sys.getfilesystemencodeerrors(),
'module_search_paths': sys.path,
}

data = json.dumps(data)
Expand Down Expand Up @@ -447,20 +448,38 @@ def get_expected_config(self, expected, env):
except json.JSONDecodeError:
self.fail(f"fail to decode stdout: {stdout!r}")

if expected['executable'] is self.GET_DEFAULT_CONFIG:
if sys.platform == 'win32':
expected['executable'] = self.test_exe
else:
if expected['program_name'] is not self.GET_DEFAULT_CONFIG:
expected['executable'] = os.path.abspath(expected['program_name'])
else:
expected['executable'] = os.path.join(os.getcwd(), '_testembed')
if expected['program_name'] is self.GET_DEFAULT_CONFIG:
expected['program_name'] = './_testembed'

for key, value in expected.items():
if value is self.GET_DEFAULT_CONFIG:
expected[key] = config[key]
expected['module_search_paths'] = config['module_search_paths']
return expected

def check_pre_config(self, config, expected):
pre_config = dict(config['pre_config'])
core_config = dict(config['core_config'])
self.assertEqual(pre_config, expected)

def check_core_config(self, config, expected):
def check_core_config(self, config, expected, add_path=None):
core_config = dict(config['core_config'])
if add_path is not None:
paths = [*expected['module_search_paths'], add_path]
if not paths[0]:
del paths[0]
self.assertEqual(core_config['module_search_paths'], paths)
for key in self.UNTESTED_CORE_CONFIG:
core_config.pop(key, None)
expected.pop(key, None)
self.assertEqual(core_config, expected)

def check_global_config(self, config):
Expand All @@ -485,7 +504,7 @@ def check_global_config(self, config):

self.assertEqual(config['global_config'], expected)

def check_config(self, testname, expected_config, expected_preconfig):
def check_config(self, testname, expected_config, expected_preconfig, add_path=None):
env = dict(os.environ)
# Remove PYTHON* environment variables to get deterministic environment
for key in list(env):
Expand All @@ -504,13 +523,13 @@ def check_config(self, testname, expected_config, expected_preconfig):
self.fail(f"fail to decode stdout: {out!r}")

expected_preconfig = dict(self.DEFAULT_PRE_CONFIG, **expected_preconfig)
expected_config = self.get_expected_config(expected_config, env)
expected_config = self.get_expected_config(expected_config, env, add_path)
for key in self.COPY_PRE_CONFIG:
if key not in expected_preconfig:
expected_preconfig[key] = expected_config[key]

self.check_pre_config(config, expected_preconfig)
self.check_core_config(config, expected_config)
self.check_core_config(config, expected_config, add_path)
self.check_global_config(config)

def test_init_default_config(self):
Expand Down Expand Up @@ -665,6 +684,15 @@ def test_preinit_isolated2(self):
}
self.check_config("preinit_isolated2", config, preconfig)

def test_init_read_set(self):
preconfig = {}
core_config = {
'program_name': './init_read_set',
'executable': 'my_executable',
}
self.check_config("init_read_set", core_config, preconfig,
add_path="init_read_set_path")


if __name__ == "__main__":
unittest.main()
48 changes: 48 additions & 0 deletions Programs/_testembed.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
/* FIXME: PEP 587 makes these functions public */
#ifndef Py_BUILD_CORE_MODULE
# define Py_BUILD_CORE_MODULE
#endif

#include <Python.h>
#include "pycore_coreconfig.h" /* FIXME: PEP 587 makes these functions public */
#include "pythread.h"
#include <inttypes.h>
#include <stdio.h>
Expand Down Expand Up @@ -679,6 +685,47 @@ static int test_init_dev_mode(void)
}


static int test_init_read_set(void)
{
_PyInitError err;
_PyCoreConfig config = _PyCoreConfig_INIT;

err = _PyCoreConfig_DecodeLocale(&config.program_name, "./init_read_set");
if (_Py_INIT_FAILED(err)) {
goto fail;
}

err = _PyCoreConfig_Read(&config);
if (_Py_INIT_FAILED(err)) {
goto fail;
}

if (_PyWstrList_Append(&config.module_search_paths,
L"init_read_set_path") < 0) {
err = _Py_INIT_NO_MEMORY();
goto fail;
}

/* override executable computed by _PyCoreConfig_Read() */
err = _PyCoreConfig_SetString(&config.executable, L"my_executable");
if (_Py_INIT_FAILED(err)) {
goto fail;
}

err = _Py_InitializeFromConfig(&config);
_PyCoreConfig_Clear(&config);
if (_Py_INIT_FAILED(err)) {
goto fail;
}
dump_config();
Py_Finalize();
return 0;

fail:
_Py_ExitInitError(err);
}


static int test_run_main(void)
{
_PyCoreConfig config = _PyCoreConfig_INIT;
Expand Down Expand Up @@ -736,6 +783,7 @@ static struct TestCase TestCases[] = {
{ "init_isolated", test_init_isolated },
{ "preinit_isolated1", test_preinit_isolated1 },
{ "preinit_isolated2", test_preinit_isolated2 },
{ "init_read_set", test_init_read_set },
{ "run_main", test_run_main },
{ NULL, NULL }
};
Expand Down