8000 [3.11] bpo-45445: Revert "bpo-45445: Fail if an invalid X-option is provided in the command line (GH-28823)" (GH-94745) by miss-islington · Pull Request #95500 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

[3.11] bpo-45445: Revert "bpo-45445: Fail if an invalid X-option is provided in the command line (GH-28823)" (GH-94745) #95500

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 1 commit into from
Jul 31, 2022
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
bpo-45445: Revert "bpo-45445: Fail if an invalid X-option is provided…
… in the command line (GH-28823)" (GH-94745)

(cherry picked from commit aa37ffd)

Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
  • Loading branch information
pablogsal authored and miss-islington committed Jul 31, 2022
commit f1eda5b75c07f391fe80c9c47135bf021c6f82cf
4 changes: 2 additions & 2 deletions Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1778,13 +1778,13 @@ always available.

.. code-block:: shell-session

$ ./python -Xpycache_prefix=some_path -Xdev
$ ./python -Xa=b -Xc
Python 3.2a3+ (py3k, Oct 16 2010, 20:14:50)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys._xoptions
{'pycache_prefix': 'some_path', 'dev': True}
{'a': 'b', 'c': True}

.. impl-detail::

Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class AuditTest(unittest.TestCase):
@support.requires_subprocess()
def do_test(self, *args):
with subprocess.Popen(
[sys.executable, "-Xutf8", AUDIT_TESTS_PY, *args],
[sys.executable, "-X utf8", AUDIT_TESTS_PY, *args],
encoding="utf-8",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
Expand All @@ -35,7 +35,7 @@ def do_test(self, *args):
def run_python(self, *args):
events = []
with subprocess.Popen(
[sys.executable, "-Xutf8", AUDIT_TESTS_PY, *args],
[sys.executable, "-X utf8", AUDIT_TESTS_PY, *args],
encoding="utf-8",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
Expand Down
13 changes: 2 additions & 11 deletions Lib/test/test_cmd_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,8 @@ def get_xoptions(*args):
opts = get_xoptions()
self.assertEqual(opts, {})

opts = get_xoptions('-Xno_debug_ranges', '-Xdev=1234')
self.assertEqual(opts, {'no_debug_ranges': True, 'dev': '1234'})

@unittest.skipIf(interpreter_requires_environment(),
'Cannot run -E tests when PYTHON env vars are required.')
def test_unknown_xoptions(self):
rc, out, err = assert_python_failure('-X', 'blech')
self.assertIn(b'Unknown value for option -X', err)
msg = b'Fatal Python error: Unknown value for option -X (see --help-xoptions)'
self.assertEqual(err.splitlines().count(msg), 1)
self.assertEqual(b'', out)
opts = get_xoptions('-Xa', '-Xb=c,d=e')
self.assertEqual(opts, {'a': True, 'b': 'c,d=e'})

def test_showrefcount(self):
def run_python(*args):
Expand Down
23 changes: 11 additions & 12 deletions Lib/test/test_embed.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def test_pre_initialization_sys_options(self):
"test_pre_initialization_sys_options", env=env)
expected_output = (
"sys.warnoptions: ['once', 'module', 'default']\n"
"sys._xoptions: {'dev': '2', 'utf8': '1'}\n"
"sys._xoptions: {'not_an_option': '1', 'also_not_an_option': '2'}\n"
"warnings.filters[:3]: ['default', 'module', 'once']\n"
)
self.assertIn(expected_output, out)
Expand Down Expand Up @@ -842,14 +842,15 @@ def test_init_from_config(self):
'argv': ['-c', 'arg2'],
'orig_argv': ['python3',
'-W', 'cmdline_warnoption',
'-X', 'dev',
'-X', 'cmdline_xoption',
'-c', 'pass',
'arg2'],
'parse_argv': 2,
'xoptions': [
'dev=3',
'utf8',
'dev',
'config_xoption1=3',
'config_xoption2=',
'config_xoption3',
'cmdline_xoption',
],
'warnoptions': [
'cmdline_warnoption',
Expand Down Expand Up @@ -1077,8 +1078,9 @@ def test_init_sys_add(self):
config = {
'faulthandler': 1,
'xoptions': [
'dev',
'utf8',
'config_xoption',
'cmdline_xoption',
'sysadd_xoption',
'faulthandler',
],
'warnoptions': [
Expand All @@ -1088,12 +1090,9 @@ def test_init_sys_add(self):
],
'orig_argv': ['python3',
'-W', 'ignore:::cmdline_warnoption',
'-X', 'utf8'],
'-X', 'cmdline_xoption'],
}
preconfig = {'utf8_mode': 1}
self.check_all_configs("test_init_sys_add", config,
expected_preconfig=preconfig,
api=API_PYTHON)
self.check_all_configs("test_init_sys_add", config, api=API_PYTHON)

def test_init_run_main(self):
code = ('import _testinternalcapi, json; '
Expand Down
18 changes: 10 additions & 8 deletions Programs/_testembed.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ static int test_pre_initialization_sys_options(void)
* relying on the caller to keep the passed in strings alive.
*/
const wchar_t *static_warnoption = L"once";
const wchar_t *static_xoption = L"utf8=1";
const wchar_t *static_xoption = L"also_not_an_option=2";
size_t warnoption_len = wcslen(static_warnoption);
size_t xoption_len = wcslen(static_xoption);
wchar_t *dynamic_once_warnoption = \
Expand All @@ -298,7 +298,7 @@ static int test_pre_initialization_sys_options(void)
PySys_AddWarnOption(L"module");
PySys_AddWarnOption(L"default");
_Py_EMBED_PREINIT_CHECK("Checking PySys_AddXOption\n");
PySys_AddXOption(L"dev=2");
PySys_AddXOption(L"not_an_option=1");
PySys_AddXOption(dynamic_xoption);

/* Delete the dynamic options early */
Expand Down Expand Up @@ -591,17 +591,18 @@ static int test_init_from_config(void)
L&quo 6D40 t;-W",
L"cmdline_warnoption",
L"-X",
L"dev",
L"cmdline_xoption",
L"-c",
L"pass",
L"arg2",
};
config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
config.parse_argv = 1;

wchar_t* xoptions[2] = {
L"dev=3",
L"utf8",
wchar_t* xoptions[3] = {
L"config_xoption1=3",
L"config_xoption2=",
L"config_xoption3",
};
config_set_wide_string_list(&config, &config.xoptions,
Py_ARRAY_LENGTH(xoptions), xoptions);
Expand Down Expand Up @@ -1425,6 +1426,7 @@ static int test_init_read_set(void)

static int test_init_sys_add(void)
{
PySys_AddXOption(L"sysadd_xoption");
PySys_AddXOption(L"faulthandler");
PySys_AddWarnOption(L"ignore:::sysadd_warnoption");

Expand All @@ -1436,14 +1438,14 @@ static int test_init_sys_add(void)
L"-W",
L"ignore:::cmdline_warnoption",
L"-X",
L"utf8",
L"cmdline_xoption",
};
config_set_argv(&am 9E88 p;config, Py_ARRAY_LENGTH(argv), argv);
config.parse_argv = 1;

PyStatus status;
status = PyWideStringList_Append(&config.xoptions,
L"dev");
L"config_xoption");
if (PyStatus_Exception(status)) {
goto fail;
}
Expand Down
48 changes: 0 additions & 48 deletions Python/initconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -2046,49 +2046,6 @@ _PyConfig_InitImportConfig(PyConfig *config)
return config_init_import(config, 1);
}

// List of known xoptions to validate against the provided ones. Note that all
// options are listed, even if they are only available if a specific macro is
// set, like -X showrefcount which requires a debug build. In this case unknown
// options are silently ignored.
const wchar_t* known_xoptions[] = {
L"faulthandler",
L"showrefcount",
L"tracemalloc",
L"importtime",
L"dev",
L"utf8",
L"pycache_prefix",
L"warn_default_encoding",
L"no_debug_ranges",
L"frozen_modules",
NULL,
};

static const wchar_t*
_Py_check_xoptions(const PyWideStringList *xoptions, const wchar_t **names)
{
for (Py_ssize_t i=0; i < xoptions->length; i++) {
const wchar_t *option = xoptions->items[i];
size_t len;
wchar_t *sep = wcschr(option, L'=');
if (sep != NULL) {
len = (sep - option);
}
else {
len = wcslen(option);
}
int found = 0;
for (const wchar_t** name = names; *name != NULL; name++) {
if (wcsncmp(option, *name, len) == 0 && (*name)[len] == L'\0') {
found = 1;
}
}
if (found == 0) {
return option;
}
}
return NULL;
}

static PyStatus
config_read(PyConfig *config, int compute_path_config)
Expand All @@ -2104,11 +2061,6 @@ config_read(PyConfig *config, int compute_path_config)
}

/* -X options */
const wchar_t* option = _Py_check_xoptions(&config->xoptions, known_xoptions);
if (option != NULL) {
return PyStatus_Error("Unknown value for option -X (see --help-xoptions)");
}

if (config_get_xoption(config, L"showrefcount")) {
config->show_ref_count = 1;
}
Expand Down
0