From 2be8a60a867973dddf89bf2713597eb09626434b Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Sat, 16 Oct 2021 12:42:43 -0600 Subject: [PATCH 1/2] Add tests for the -X option. --- Lib/test/test_cmd_line.py | 15 +++++++++++++++ Lib/test/test_embed.py | 24 +++++++++++++++++++++++ Programs/_testembed.c | 40 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 1dc8c45885cbef..86ee27485c9642 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -123,6 +123,21 @@ def run_python(*args): else: self.assertEqual(err, b'') + def test_xoption_frozen_modules(self): + tests = { + ('=on', 'FrozenImporter'), + ('=off', 'SourceFileLoader'), + ('=', 'FrozenImporter'), + ('', 'FrozenImporter'), + } + for raw, expected in tests: + cmd = ['-X', f'frozen_modules{raw}', + #'-c', 'import os; print(os.__spec__.loader.__name__, end="")'] + '-c', 'import os; print(os.__spec__.loader, end="")'] + with self.subTest(raw): + res = assert_python_ok(*cmd) + self.assertRegex(res.out.decode('utf-8'), expected) + def test_run_module(self): # Test expected operation of the '-m' switch # Switch needs an argument diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 4cbb4c2c1ce366..8875446d65cf1d 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -1458,6 +1458,30 @@ def test_get_argc_argv(self): self.run_embedded_interpreter("test_get_argc_argv") # ignore output + def test_init_use_frozen_modules(self): + tests = { + ('=on', 1), + ('=off', 0), + ('=', 1), + ('', 1), + } + for raw, expected in tests: + optval = f'frozen_modules{raw}' + config = { + 'parse_argv': 2, + 'argv': ['-c'], + 'orig_argv': ['./argv0', '-X', optval, '-c', 'pass'], + 'program_name': './argv0', + 'run_command': 'pass\n', + 'use_environment': 1, + 'xoptions': [optval], + 'use_frozen_modules': expected, + } + with self.subTest(raw): + self.check_all_configs("test_init_use_frozen_modules", + config, api=API_PYTHON, + env={'TESTFROZEN': raw}) + class SetConfigTests(unittest.TestCase): def test_set_config(self): diff --git a/Programs/_testembed.c b/Programs/_testembed.c index b61fe3461bdc98..9de6ffdd64c492 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1726,6 +1726,45 @@ static int test_get_argc_argv(void) } +static int check_use_frozen_modules(const char *rawval) +{ + wchar_t optval[100]; + if (swprintf(optval, 100, L"frozen_modules%s", rawval) < 0) { + error("rawval is too long"); + return -1; + } + + PyConfig config; + PyConfig_InitPythonConfig(&config); + + config.parse_argv = 1; + + wchar_t* argv[] = { + L"./argv0", + L"-X", + optval, + L"-c", + L"pass", + }; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + init_from_config_clear(&config); + + dump_config(); + Py_Finalize(); + return 0; +} + +static int test_init_use_frozen_modules(void) +{ + const char *envvar = getenv("TESTFROZEN"); + if (envvar == NULL) { + error("missing TESTFROZEN env var"); + return 1; + } + return check_use_frozen_modules(envvar); +} + + static int test_unicode_id_init(void) { // bpo-42882: Test that _PyUnicode_FromId() works @@ -1912,6 +1951,7 @@ static struct TestCase TestCases[] = { {"test_run_main", test_run_main}, {"test_run_main_loop", test_run_main_loop}, {"test_get_argc_argv", test_get_argc_argv}, + {"test_init_use_frozen_modules", test_init_use_frozen_modules}, // Audit {"test_open_code_hook", test_open_code_hook}, From 0bb7a8776aa06eb758ca508bf58d7468a9faa61a Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 25 Oct 2021 11:57:39 -0600 Subject: [PATCH 2/2] Do not send "=". --- Lib/test/test_embed.py | 8 ++++---- Programs/_testembed.c | 9 ++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 8875446d65cf1d..2ff0a877afac13 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -1477,10 +1477,10 @@ def test_init_use_frozen_modules(self): 'xoptions': [optval], 'use_frozen_modules': expected, } - with self.subTest(raw): - self.check_all_configs("test_init_use_frozen_modules", - config, api=API_PYTHON, - env={'TESTFROZEN': raw}) + env = {'TESTFROZEN': raw[1:]} if raw else None + with self.subTest(repr(raw)): + self.check_all_configs("test_init_use_frozen_modules", config, + api=API_PYTHON, env=env) class SetConfigTests(unittest.TestCase): diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 9de6ffdd64c492..773c6c3e9900a5 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1729,7 +1729,10 @@ static int test_get_argc_argv(void) static int check_use_frozen_modules(const char *rawval) { wchar_t optval[100]; - if (swprintf(optval, 100, L"frozen_modules%s", rawval) < 0) { + if (rawval == NULL) { + wcscpy(optval, L"frozen_modules"); + } + else if (swprintf(optval, 100, L"frozen_modules=%s", rawval) < 0) { error("rawval is too long"); return -1; } @@ -1757,10 +1760,6 @@ static int check_use_frozen_modules(const char *rawval) static int test_init_use_frozen_modules(void) { const char *envvar = getenv("TESTFROZEN"); - if (envvar == NULL) { - error("missing TESTFROZEN env var"); - return 1; - } return check_use_frozen_modules(envvar); }