[Python-checkins] bpo-36763: Remove _PyCoreConfig.program (GH-13373)

Victor Stinner webhook-mailer at python.org
Fri May 17 05:12:16 EDT 2019


https://github.com/python/cpython/commit/fed02e15b39b6f1521ea21654be5fc0757a8720a
commit: fed02e15b39b6f1521ea21654be5fc0757a8720a
branch: master
author: Victor Stinner <vstinner at redhat.com>
committer: GitHub <noreply at github.com>
date: 2019-05-17T11:12:09+02:00
summary:

bpo-36763: Remove _PyCoreConfig.program (GH-13373)

Use _PyCoreConfig.program_name instead.

files:
M Include/cpython/coreconfig.h
M Lib/test/test_embed.py
M Modules/main.c
M Programs/_testembed.c
M Python/coreconfig.c

diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h
index b531118ea3cf..1ba2663c9667 100644
--- a/Include/cpython/coreconfig.h
+++ b/Include/cpython/coreconfig.h
@@ -218,11 +218,15 @@ typedef struct {
        always exists and is never empty. */
     _PyWstrList argv;
 
-    /* Program: argv[0] or "".
-       Used to display Python usage if parsing command line arguments fails.
-       Used to initialize the default value of program_name */
-    wchar_t *program;
-    wchar_t *program_name;    /* Program name, see also Py_GetProgramName() */
+    /* Program name:
+
+       - If Py_SetProgramName() was called, use its value.
+       - On macOS, use PYTHONEXECUTABLE environment variable if set.
+       - If WITH_NEXT_FRAMEWORK macro is defined, use __PYVENV_LAUNCHER__
+         environment variable is set.
+       - Use argv[0] if available and non-empty.
+       - Use "python" on Windows, or "python3 on other platforms. */
+    wchar_t *program_name;
 
     _PyWstrList xoptions;     /* Command line -X options */
     _PyWstrList warnoptions;  /* Warnings options */
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index b1872ace8a60..4012a389d750 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -306,7 +306,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         'program_name': GET_DEFAULT_CONFIG,
         'parse_argv': 1,
         'argv': [""],
-        'program': '',
 
         'xoptions': [],
         'warnoptions': [],
@@ -586,7 +585,6 @@ def test_init_from_config(self):
             'pycache_prefix': 'conf_pycache_prefix',
             'program_name': './conf_program_name',
             'argv': ['-c', 'arg2'],
-            'program': 'conf_program',
             'xoptions': ['core_xoption1=3', 'core_xoption2=', 'core_xoption3'],
             'warnoptions': ['error::ResourceWarning', 'default::BytesWarning'],
             'run_command': 'pass\n',
@@ -704,7 +702,6 @@ def test_init_run_main(self):
                 'print(json.dumps(_testinternalcapi.get_configs()))')
         core_config = {
             'argv': ['-c', 'arg2'],
-            'program': 'python3',
             'program_name': './python3',
             'run_command': code + '\n',
         }
@@ -716,7 +713,6 @@ def test_init_main(self):
                 'print(json.dumps(_testinternalcapi.get_configs()))')
         core_config = {
             'argv': ['-c', 'arg2'],
-            'program': 'python3',
             'program_name': './python3',
             'run_command': code + '\n',
             '_init_main': 0,
@@ -728,7 +724,6 @@ def test_init_dont_parse_argv(self):
         core_config = {
             'argv': ['-v', '-c', 'arg1', '-W', 'arg2'],
             'parse_argv': 0,
-            'program': 'program',
         }
         self.check_config("init_dont_parse_argv", core_config, {})
 
diff --git a/Modules/main.c b/Modules/main.c
index b47ac70d62cf..bb103c28a3e2 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -283,7 +283,7 @@ pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)
         else
             cfilename = "<unprintable file name>";
         fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
-                config->program, cfilename, err, strerror(err));
+                config->program_name, cfilename, err, strerror(err));
         PyMem_RawFree(cfilename_buffer);
         return 2;
     }
@@ -303,7 +303,7 @@ pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)
     if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) {
         fprintf(stderr,
                 "%ls: '%ls' is a directory, cannot continue\n",
-                config->program, filename);
+                config->program_name, filename);
         fclose(fp);
         return 1;
     }
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index 87d159fe7219..b1b7c6e0ffc3 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -433,8 +433,6 @@ static int test_init_from_config(void)
     config.argv.length = Py_ARRAY_LENGTH(argv);
     config.argv.items = argv;
 
-    config.program = L"conf_program";
-
     static wchar_t* xoptions[3] = {
         L"core_xoption1=3",
         L"core_xoption2=",
@@ -532,7 +530,6 @@ static int test_init_dont_parse_argv(void)
         L"arg2",
     };
 
-    config.program = L"program";
     config.program_name = L"./_testembed";
 
     config.argv.length = Py_ARRAY_LENGTH(argv);
diff --git a/Python/coreconfig.c b/Python/coreconfig.c
index ce778a640d3c..c20ae2151c9c 100644
--- a/Python/coreconfig.c
+++ b/Python/coreconfig.c
@@ -492,7 +492,6 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
     CLEAR(config->module_search_path_env);
     CLEAR(config->home);
     CLEAR(config->program_name);
-    CLEAR(config->program);
 
     _PyWstrList_Clear(&config->argv);
     _PyWstrList_Clear(&config->warnoptions);
@@ -626,7 +625,6 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
     COPY_WSTR_ATTR(module_search_path_env);
     COPY_WSTR_ATTR(home);
     COPY_WSTR_ATTR(program_name);
-    COPY_WSTR_ATTR(program);
 
     COPY_ATTR(parse_argv);
     COPY_WSTRLIST(argv);
@@ -732,7 +730,6 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
     SET_ITEM_WSTR(program_name);
     SET_ITEM_INT(parse_argv);
     SET_ITEM_WSTRLIST(argv);
-    SET_ITEM_WSTR(program);
     SET_ITEM_WSTRLIST(xoptions);
     SET_ITEM_WSTRLIST(warnoptions);
     SET_ITEM_WSTR(module_search_path_env);
@@ -918,7 +915,6 @@ static _PyInitError
 config_init_program_name(_PyCoreConfig *config)
 {
     _PyInitError err;
-    assert(config->program_name == NULL);
 
     /* If Py_SetProgramName() was called, use its value */
     const wchar_t *program_name = _Py_path_config.program_name;
@@ -967,16 +963,17 @@ config_init_program_name(_PyCoreConfig *config)
 #endif   /* WITH_NEXT_FRAMEWORK */
 #endif   /* __APPLE__ */
 
-    /* Use argv[0] by default, if available */
-    if (config->program != NULL) {
-        err = _PyCoreConfig_SetString(&config->program_name, config->program);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+    /* Use argv[0] if available and non-empty */
+    const _PyWstrList *argv = &config->argv;
+    if (argv->length >= 1 && argv->items[0][0] != L'\0') {
+        config->program_name = _PyMem_RawWcsdup(argv->items[0]);
+        if (config->program_name == NULL) {
+            return _Py_INIT_NO_MEMORY();
         }
         return _Py_INIT_OK();
     }
 
-    /* Last fall back: hardcoded string */
+    /* Last fall back: hardcoded name */
 #ifdef MS_WINDOWS
     const wchar_t *default_program_name = L"python";
 #else
@@ -1518,13 +1515,6 @@ config_read(_PyCoreConfig *config)
         }
     }
 
-    if (config->program_name == NULL) {
-        err = config_init_program_name(config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
-        }
-    }
-
     if (config->executable == NULL) {
         err = config_init_executable(config);
         if (_Py_INIT_FAILED(err)) {
@@ -1678,6 +1668,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
     _PyInitError err;
     const _PyWstrList *argv = &config->argv;
     int print_version = 0;
+    const wchar_t* program = config->program_name;
 
     _PyOS_ResetGetOpt();
     do {
@@ -1734,7 +1725,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
             } else {
                 fprintf(stderr, "--check-hash-based-pycs must be one of "
                         "'default', 'always', or 'never'\n");
-                config_usage(1, config->program);
+                config_usage(1, program);
                 return _Py_INIT_EXIT(2);
             }
             break;
@@ -1794,7 +1785,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
 
         case 'h':
         case '?':
-            config_usage(0, config->program);
+            config_usage(0, program);
             return _Py_INIT_EXIT(0);
 
         case 'V':
@@ -1819,7 +1810,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
 
         default:
             /* unknown argument: parsing failed */
-            config_usage(1, config->program);
+            config_usage(1, program);
             return _Py_INIT_EXIT(2);
         }
     } while (1);
@@ -1892,26 +1883,6 @@ config_init_env_warnoptions(const _PyCoreConfig *config, _PyWstrList *warnoption
 }
 
 
-static _PyInitError
-config_init_program(_PyCoreConfig *config)
-{
-    const _PyWstrList *argv = &config->argv;
-    wchar_t *program;
-    if (argv->length >= 1) {
-        program = argv->items[0];
-    }
-    else {
-        program = L"";
-    }
-    config->program = _PyMem_RawWcsdup(program);
-    if (config->program == NULL) {
-        return _Py_INIT_NO_MEMORY();
-    }
-
-    return _Py_INIT_OK();
-}
-
-
 static int
 config_add_warnoption(_PyCoreConfig *config, const wchar_t *option)
 {
@@ -2084,10 +2055,10 @@ config_read_cmdline(_PyCoreConfig *config)
         config->parse_argv = 1;
     }
 
-    if (config->program == NULL) {
-        err = config_init_program(config);
+    if (config->program_name == NULL) {
+        err = config_init_program_name(config);
         if (_Py_INIT_FAILED(err)) {
-            goto done;
+            return err;
         }
     }
 
@@ -2218,6 +2189,8 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
         goto done;
     }
 
+    /* precmdline.argv is a copy of config.argv which is modified
+       by config_read_cmdline() */
     const _PyWstrList *argv = &precmdline.argv;
     if (_Py_SetArgcArgv(argv->length, argv->items) < 0) {
         err = _Py_INIT_NO_MEMORY();
@@ -2246,7 +2219,6 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
     assert(config->configure_c_stdio >= 0);
     assert(config->buffered_stdio >= 0);
     assert(config->program_name != NULL);
-    assert(config->program != NULL);
     assert(_PyWstrList_CheckConsistency(&config->argv));
     /* sys.argv must be non-empty: empty argv is replaced with [''] */
     assert(config->argv.length >= 1);



More information about the Python-checkins mailing list