| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1729,13 +1729,13 @@ always available. | |||
| 1729 | 1729 | ||
| 1730 | 1730 | .. code-block:: shell-session | |
| 1731 | 1731 | ||
| 1732 | - $ ./python -Xa=b -Xc | ||
| 1732 | + $ ./python -Xpycache_prefix=some_path -Xdev | ||
| 1733 | 1733 | Python 3.2a3+ (py3k, Oct 16 2010, 20:14:50) | |
| 1734 | 1734 | [GCC 4.4.3] on linux2 | |
| 1735 | 1735 | Type "help", "copyright", "credits" or "license" for more information. | |
| 1736 | 1736 | >>> import sys | |
| 1737 | 1737 | >>> sys._xoptions | |
| 1738 | - {'a': 'b', 'c': True} | ||
| 1738 | + {'pycache_prefix': 'some_path', 'dev': True} | ||
| 1739 | 1739 | ||
| 1740 | 1740 | .. impl-detail:: | |
| 1741 | 1741 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,7 +18,7 @@ | |||
| 18 | 18 | class AuditTest(unittest.TestCase): | |
| 19 | 19 | def do_test(self, *args): | |
| 20 | 20 | with subprocess.Popen( | |
| 21 | - [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], | ||
| 21 | + [sys.executable, "-Xutf8", AUDIT_TESTS_PY, *args], | ||
| 22 | 22 | encoding="utf-8", | |
| 23 | 23 | stdout=subprocess.PIPE, | |
| 24 | 24 | stderr=subprocess.PIPE, | |
@@ -32,7 +32,7 @@ def do_test(self, *args): | |||
| 32 | 32 | def run_python(self, *args): | |
| 33 | 33 | events = [] | |
| 34 | 34 | with subprocess.Popen( | |
| 35 | - [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], | ||
| 35 | + [sys.executable, "-Xutf8", AUDIT_TESTS_PY, *args], | ||
| 36 | 36 | encoding="utf-8", | |
| 37 | 37 | stdout=subprocess.PIPE, | |
| 38 | 38 | stderr=subprocess.PIPE, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -83,8 +83,17 @@ def get_xoptions(*args): | |||
| 83 | 83 | opts = get_xoptions() | |
| 84 | 84 | self.assertEqual(opts, {}) | |
| 85 | 85 | ||
| 86 | - opts = get_xoptions('-Xa', '-Xb=c,d=e') | ||
| 87 | - self.assertEqual(opts, {'a': True, 'b': 'c,d=e'}) | ||
| 86 | + opts = get_xoptions('-Xno_debug_ranges', '-Xdev=1234') | ||
| 87 | + self.assertEqual(opts, {'no_debug_ranges': True, 'dev': '1234'}) | ||
| 88 | + | ||
| 89 | + @unittest.skipIf(interpreter_requires_environment(), | ||
| 90 | + 'Cannot run -E tests when PYTHON env vars are required.') | ||
| 91 | + def test_unknown_xoptions(self): | ||
| 92 | + rc, out, err = assert_python_failure('-X', 'blech') | ||
| 93 | + self.assertIn(b'Unknown value for option -X', err) | ||
| 94 | + msg = b'Fatal Python error: Unknown value for option -X' | ||
| 95 | + self.assertEqual(err.splitlines().count(msg), 1) | ||
| 96 | + self.assertEqual(b'', out) | ||
| 88 | 97 | ||
| 89 | 98 | def test_showrefcount(self): | |
| 90 | 99 | def run_python(*args): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -273,7 +273,7 @@ def test_pre_initialization_sys_options(self): | |||
| 273 | 273 | "test_pre_initialization_sys_options", env=env) | |
| 274 | 274 | expected_output = ( | |
| 275 | 275 | "sys.warnoptions: ['once', 'module', 'default']\n" | |
| 276 | - "sys._xoptions: {'not_an_option': '1', 'also_not_an_option': '2'}\n" | ||
| 276 | + "sys._xoptions: {'dev': '2', 'utf8': '1'}\n" | ||
| 277 | 277 | "warnings.filters[:3]: ['default', 'module', 'once']\n" | |
| 278 | 278 | ) | |
| 279 | 279 | self.assertIn(expected_output, out) | |
@@ -820,15 +820,14 @@ def test_init_from_config(self): | |||
| 820 | 820 | 'argv': ['-c', 'arg2'], | |
| 821 | 821 | 'orig_argv': ['python3', | |
| 822 | 822 | '-W', 'cmdline_warnoption', | |
| 823 | - '-X', 'cmdline_xoption', | ||
| 823 | + '-X', 'dev', | ||
| 824 | 824 | '-c', 'pass', | |
| 825 | 825 | 'arg2'], | |
| 826 | 826 | 'parse_argv': 2, | |
| 827 | 827 | 'xoptions': [ | |
| 828 | - 'config_xoption1=3', | ||
| 829 | - 'config_xoption2=', | ||
| 830 | - 'config_xoption3', | ||
| 831 | - 'cmdline_xoption', | ||
| 828 | + 'dev=3', | ||
| 829 | + 'utf8', | ||
| 830 | + 'dev', | ||
| 832 | 831 | ], | |
| 833 | 832 | 'warnoptions': [ | |
| 834 | 833 | 'cmdline_warnoption', | |
@@ -1046,9 +1045,8 @@ def test_init_sys_add(self): | |||
| 1046 | 1045 | config = { | |
| 1047 | 1046 | 'faulthandler': 1, | |
| 1048 | 1047 | 'xoptions': [ | |
| 1049 | - 'config_xoption', | ||
| 1050 | - 'cmdline_xoption', | ||
| 1051 | - 'sysadd_xoption', | ||
| 1048 | + 'dev', | ||
| 1049 | + 'utf8', | ||
| 1052 | 1050 | 'faulthandler', | |
| 1053 | 1051 | ], | |
| 1054 | 1052 | 'warnoptions': [ | |
@@ -1058,9 +1056,12 @@ def test_init_sys_add(self): | |||
| 1058 | 1056 | ], | |
| 1059 | 1057 | 'orig_argv': ['python3', | |
| 1060 | 1058 | '-W', 'ignore:::cmdline_warnoption', | |
| 1061 | - '-X', 'cmdline_xoption'], | ||
| 1059 | + '-X', 'utf8'], | ||
| 1062 | 1060 | } | |
| 1063 | - self.check_all_configs("test_init_sys_add", config, api=API_PYTHON) | ||
| 1061 | + preconfig = {'utf8_mode': 1} | ||
| 1062 | + self.check_all_configs("test_init_sys_add", config, | ||
| 1063 | + expected_preconfig=preconfig, | ||
| 1064 | + api=API_PYTHON) | ||
| 1064 | 1065 | ||
| 1065 | 1066 | def test_init_run_main(self): | |
| 1066 | 1067 | code = ('import _testinternalcapi, json; ' | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Python now fails to initialize if it finds an invalid :option:`-X` option in the | ||
| 2 | + command line. Patch by Pablo Galindo. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -211,7 +211,7 @@ static int test_pre_initialization_sys_options(void) | |||
| 211 | 211 | * relying on the caller to keep the passed in strings alive. | |
| 212 | 212 | */ | |
| 213 | 213 | const wchar_t *static_warnoption = L"once"; | |
| 214 | - const wchar_t *static_xoption = L"also_not_an_option=2"; | ||
| 214 | + const wchar_t *static_xoption = L"utf8=1"; | ||
| 215 | 215 | size_t warnoption_len = wcslen(static_warnoption); | |
| 216 | 216 | size_t xoption_len = wcslen(static_xoption); | |
| 217 | 217 | wchar_t *dynamic_once_warnoption = \ | |
@@ -230,7 +230,7 @@ static int test_pre_initialization_sys_options(void) | |||
| 230 | 230 | PySys_AddWarnOption(L"module"); | |
| 231 | 231 | PySys_AddWarnOption(L"default"); | |
| 232 | 232 | _Py_EMBED_PREINIT_CHECK("Checking PySys_AddXOption\n"); | |
| 233 | - PySys_AddXOption(L"not_an_option=1"); | ||
| 233 | + PySys_AddXOption(L"dev=2"); | ||
| 234 | 234 | PySys_AddXOption(dynamic_xoption); | |
| 235 | 235 | ||
| 236 | 236 | /* Delete the dynamic options early */ | |
@@ -548,18 +548,17 @@ static int test_init_from_config(void) | |||
| 548 | 548 | L"-W", | |
| 549 | 549 | L"cmdline_warnoption", | |
| 550 | 550 | L"-X", | |
| 551 | - L"cmdline_xoption", | ||
| 551 | + L"dev", | ||
| 552 | 552 | L"-c", | |
| 553 | 553 | L"pass", | |
| 554 | 554 | L"arg2", | |
| 555 | 555 | }; | |
| 556 | 556 | config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); | |
| 557 | 557 | config.parse_argv = 1; | |
| 558 | 558 | ||
| 559 | - wchar_t* xoptions[3] = { | ||
| 560 | - L"config_xoption1=3", | ||
| 561 | - L"config_xoption2=", | ||
| 562 | - L"config_xoption3", | ||
| 559 | + wchar_t* xoptions[2] = { | ||
| 560 | + L"dev=3", | ||
| 561 | + L"utf8", | ||
| 563 | 562 | }; | |
| 564 | 563 | config_set_wide_string_list(&config, &config.xoptions, | |
| 565 | 564 | Py_ARRAY_LENGTH(xoptions), xoptions); | |
@@ -1375,7 +1374,6 @@ static int test_init_read_set(void) | |||
| 1375 | 1374 | ||
| 1376 | 1375 | static int test_init_sys_add(void) | |
| 1377 | 1376 | { | |
| 1378 | - PySys_AddXOption(L"sysadd_xoption"); | ||
| 1379 | 1377 | PySys_AddXOption(L"faulthandler"); | |
| 1380 | 1378 | PySys_AddWarnOption(L"ignore:::sysadd_warnoption"); | |
| 1381 | 1379 | ||
@@ -1387,14 +1385,14 @@ static int test_init_sys_add(void) | |||
| 1387 | 1385 | L"-W", | |
| 1388 | 1386 | L"ignore:::cmdline_warnoption", | |
| 1389 | 1387 | L"-X", | |
| 1390 | - L"cmdline_xoption", | ||
| 1388 | + L"utf8", | ||
| 1391 | 1389 | }; | |
| 1392 | 1390 | config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); | |
| 1393 | 1391 | config.parse_argv = 1; | |
| 1394 | 1392 | ||
| 1395 | 1393 | PyStatus status; | |
| 1396 | 1394 | status = PyWideStringList_Append(&config.xoptions, | |
| 1397 | - L"config_xoption"); | ||
| 1395 | + L"dev"); | ||
| 1398 | 1396 | if (PyStatus_Exception(status)) { | |
| 1399 | 1397 | goto fail; | |
| 1400 | 1398 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2129,6 +2129,49 @@ _PyConfig_InitImportConfig(PyConfig *config) | |||
| 2129 | 2129 | return config_init_import(config, 1); | |
| 2130 | 2130 | } | |
| 2131 | 2131 | ||
| 2132 | + // List of known xoptions to validate against the provided ones. Note that all | ||
| 2133 | + // options are listed, even if they are only available if a specific macro is | ||
| 2134 | + // set, like -X showrefcount which requires a debug build. In this case unknown | ||
| 2135 | + // options are silently ignored. | ||
| 2136 | + const wchar_t* known_xoptions[] = { | ||
| 2137 | + L"faulthandler", | ||
| 2138 | + L"showrefcount", | ||
| 2139 | + L"tracemalloc", | ||
| 2140 | + L"importtime", | ||
| 2141 | + L"dev", | ||
| 2142 | + L"utf8", | ||
| 2143 | + L"pycache_prefix", | ||
| 2144 | + L"warn_default_encoding", | ||
| 2145 | + L"no_debug_ranges", | ||
| 2146 | + L"frozen_modules", | ||
| 2147 | + NULL, | ||
| 2148 | + }; | ||
| 2149 | + | ||
| 2150 | + static const wchar_t* | ||
| 2151 | + _Py_check_xoptions(const PyWideStringList *xoptions, const wchar_t **names) | ||
| 2152 | + { | ||
| 2153 | + for (Py_ssize_t i=0; i < xoptions->length; i++) { | ||
| 2154 | + const wchar_t *option = xoptions->items[i]; | ||
| 2155 | + size_t len; | ||
| 2156 | + wchar_t *sep = wcschr(option, L'='); | ||
| 2157 | + if (sep != NULL) { | ||
| 2158 | + len = (sep - option); | ||
| 2159 | + } | ||
| 2160 | + else { | ||
| 2161 | + len = wcslen(option); | ||
| 2162 | + } | ||
| 2163 | + int found = 0; | ||
| 2164 | + for (const wchar_t** name = names; *name != NULL; name++) { | ||
| 2165 | + if (wcsncmp(option, *name, len) == 0 && (*name)[len] == L'\0') { | ||
| 2166 | + found = 1; | ||
| 2167 | + } | ||
| 2168 | + } | ||
| 2169 | + if (found == 0) { | ||
| 2170 | + return option; | ||
| 2171 | + } | ||
| 2172 | + } | ||
| 2173 | + return NULL; | ||
| 2174 | + } | ||
| 2132 | 2175 | ||
| 2133 | 2176 | static PyStatus | |
| 2134 | 2177 | config_read(PyConfig *config, int compute_path_config) | |
@@ -2144,6 +2187,11 @@ config_read(PyConfig *config, int compute_path_config) | |||
| 2144 | 2187 | } | |
| 2145 | 2188 | ||
| 2146 | 2189 | /* -X options */ | |
| 2190 | + const wchar_t* option = _Py_check_xoptions(&config->xoptions, known_xoptions); | ||
| 2191 | + if (option != NULL) { | ||
| 2192 | + return PyStatus_Error("Unknown value for option -X"); | ||
| 2193 | + } | ||
| 2194 | + | ||
| 2147 | 2195 | if (config_get_xoption(config, L"showrefcount")) { | |
| 2148 | 2196 | config->show_ref_count = 1; | |
| 2149 | 2197 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + def foo(a=3, *, c, d=2): | ||
| 2 | + pass | ||
| 3 | + foo() | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments