summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-12-19 22:48:17 (GMT)
committerGitHub <noreply@github.com>2017-12-19 22:48:17 (GMT)
commitc4bca951065f4b2b6833f6ce7a0721e863e2343e (patch)
tree81105844562d19d84e13c051c6a73c7c133ffeb7
parentf4e21a2a72f76d75a6cc6f74faf910a5f3108482 (diff)
downloadcpython-c4bca951065f4b2b6833f6ce7a0721e863e2343e.zip
cpython-c4bca951065f4b2b6833f6ce7a0721e863e2343e.tar.gz
cpython-c4bca951065f4b2b6833f6ce7a0721e863e2343e.tar.bz2
bpo-32030: Add _PyCoreConfig.argv (#4934)
* Add argc and argv to _PyCoreConfig * _PyMainInterpreterConfig_Read() now builds its argv from _PyCoreConfig.arg * Move _PyMain.env_warning_options into _Py_CommandLineDetails * Reorder pymain_free()
-rw-r--r--Include/pylifecycle.h4
-rw-r--r--Include/pystate.h10
-rw-r--r--Modules/main.c370
3 files changed, 233 insertions, 151 deletions
diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h
index 3ea8ad6..77c4330 100644
--- a/Include/pylifecycle.h
+++ b/Include/pylifecycle.h
@@ -61,7 +61,9 @@ PyAPI_FUNC(int) _PyCoreConfig_Copy(
_PyCoreConfig *config,
const _PyCoreConfig *config2);
-PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *, _PyCoreConfig *);
+PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read(
+ _PyMainInterpreterConfig *config,
+ const _PyCoreConfig *core_config);
PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *);
PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy(
_PyMainInterpreterConfig *config,
diff --git a/Include/pystate.h b/Include/pystate.h
index fff134a..ed5b6c9 100644
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -47,10 +47,18 @@ typedef struct {
wchar_t *home; /* PYTHONHOME environment variable,
see also Py_SetPythonHome(). */
wchar_t *program_name; /* Program name, see also Py_GetProgramName() */
+
+ int argc; /* Number of command line arguments,
+ -1 means unset */
+ wchar_t **argv; /* sys.argv, ignored if argc is negative */
} _PyCoreConfig;
#define _PyCoreConfig_INIT \
- (_PyCoreConfig){.use_hash_seed = -1, .coerce_c_locale = -1, .utf8_mode = -1}
+ (_PyCoreConfig){ \
+ .use_hash_seed = -1, \
+ .coerce_c_locale = -1, \
+ .utf8_mode = -1, \
+ .argc = -1}
/* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */
/* Placeholders while working on the new configuration API
diff --git a/Modules/main.c b/Modules/main.c
index 360a085..59e535d 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -229,7 +229,7 @@ error:
static int
-pymain_run_module(wchar_t *modname, int set_argv0)
+pymain_run_module(const wchar_t *modname, int set_argv0)
{
PyObject *module, *runpy, *runmodule, *runargs, *result;
runpy = PyImport_ImportModule("runpy");
@@ -279,7 +279,7 @@ pymain_run_module(wchar_t *modname, int set_argv0)
}
static PyObject *
-pymain_get_importer(wchar_t *filename)
+pymain_get_importer(const wchar_t *filename)
{
PyObject *sys_path0 = NULL, *importer;
@@ -384,9 +384,10 @@ typedef struct {
} _Py_OptList;
typedef struct {
- wchar_t *filename; /* Trailing arg without -c or -m */
+ wchar_t **argv;
+ const wchar_t *filename; /* Trailing arg without -c or -m */
wchar_t *command; /* -c argument */
- wchar_t *module; /* -m argument */
+ const wchar_t *module; /* -m argument */
_Py_OptList warning_options; /* -W options */
int print_help; /* -h, -? options */
int print_version; /* -V option */
@@ -411,6 +412,7 @@ typedef struct {
int legacy_windows_stdio; /* Py_LegacyWindowsStdioFlag,
PYTHONLEGACYWINDOWSSTDIO */
#endif
+ _Py_OptList env_warning_options; /* PYTHONWARNINGS env var */
} _Py_CommandLineDetails;
/* Structure used by Py_Main() to pass data to subfunctions */
@@ -429,16 +431,11 @@ typedef struct {
int run_code;
/* Error message if a function failed */
_PyInitError err;
- /* PYTHONWARNINGS env var */
- _Py_OptList env_warning_options;
int argc;
- wchar_t **argv;
int use_bytes_argv;
char **bytes_argv;
-
- int sys_argc;
- wchar_t **sys_argv;
+ wchar_t **wchar_argv;
} _PyMain;
/* .cmdline is initialized to zeros */
@@ -462,118 +459,141 @@ pymain_optlist_clear(_Py_OptList *list)
}
-/* Free global variables which cannot be freed in Py_Finalize():
- configuration options set before Py_Initialize() which should
- remain valid after Py_Finalize(), since Py_Initialize()/Py_Finalize() can
- be called multiple times.
-
- Called with the current memory allocators. */
static void
-pymain_free_globals(_PyMain *pymain)
+clear_argv(int argc, wchar_t **argv)
{
- _PyPathConfig_Clear(&_Py_path_config);
- _PyImport_Fini2();
-
-#ifdef __INSURE__
- /* Insure++ is a memory analysis tool that aids in discovering
- * memory leaks and other memory problems. On Python exit, the
- * interned string dictionaries are flagged as being in use at exit
- * (which it is). Under normal circumstances, this is fine because
- * the memory will be automatically reclaimed by the system. Under
- * memory debugging, it's a huge source of useless noise, so we
- * trade off slower shutdown for less distraction in the memory
- * reports. -baw
- */
- _Py_ReleaseInternedUnicodeStrings();
-#endif /* __INSURE__ */
-}
-
-
-/* Clear argv allocated by pymain_decode_bytes_argv() */
-static void
-pymain_clear_bytes_argv(_PyMain *pymain, int argc)
-{
- if (pymain->use_bytes_argv && pymain->argv != NULL) {
- for (int i = 0; i < argc; i++) {
- PyMem_RawFree(pymain->argv[i]);
- }
- PyMem_RawFree(pymain->argv);
- pymain->argv = NULL;
+ for (int i=0; i < argc; i++) {
+ PyMem_RawFree(argv[i]);
}
+ PyMem_RawFree(argv);
}
static int
-pymain_decode_bytes_argv(_PyMain *pymain)
+pymain_init_cmdline_argv(_PyMain *pymain)
{
- assert(pymain->argv == NULL);
+ assert(pymain->cmdline.argv == NULL);
+
+ if (!pymain->use_bytes_argv) {
+ pymain->cmdline.argv = pymain->wchar_argv;
+ return 0;
+ }
/* +1 for a the NULL terminator */
size_t size = sizeof(wchar_t*) * (pymain->argc + 1);
- pymain->argv = (wchar_t **)PyMem_RawMalloc(size);
- if (pymain->argv == NULL) {
+ wchar_t** argv = (wchar_t **)PyMem_RawMalloc(size);
+ if (argv == NULL) {
pymain->err = _Py_INIT_NO_MEMORY();
return -1;
}
for (int i = 0; i < pymain->argc; i++) {
size_t len;
- pymain->argv[i] = Py_DecodeLocale(pymain->bytes_argv[i], &len);
- if (pymain->argv[i] == NULL) {
- pymain_clear_bytes_argv(pymain, i);
+ wchar_t *arg = Py_DecodeLocale(pymain->bytes_argv[i], &len);
+ if (arg == NULL) {
+ clear_argv(i, argv);
pymain->err = DECODE_LOCALE_ERR("command line arguments",
(Py_ssize_t)len);
return -1;
}
+ argv[i] = arg;
}
- pymain->argv[pymain->argc] = NULL;
+ argv[pymain->argc] = NULL;
+
+ pymain->cmdline.argv = argv;
return 0;
}
static void
-pymain_clear_pymain(_PyMain *pymain)
+pymain_clear_cmdline(_PyMain *pymain)
{
+ /* Clear orig_argv: pymain_init_python_core() uses a borrowed pointer
+ to pymain->argv */
+ orig_argc = 0;
+ orig_argv = NULL;
+
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
pymain_optlist_clear(&cmdline->warning_options);
pymain_optlist_clear(&cmdline->xoptions);
PyMem_RawFree(cmdline->command);
cmdline->command = NULL;
+ pymain_optlist_clear(&cmdline->env_warning_options);
+
+ if (pymain->use_bytes_argv && cmdline->argv != NULL) {
+ clear_argv(pymain->argc, cmdline->argv);
+ }
+ cmdline->argv = NULL;
+}
+
- PyMem_RawFree(pymain->sys_argv);
- pymain->sys_argv = NULL;
- pymain_optlist_clear(&pymain->env_warning_options);
- pymain_clear_bytes_argv(pymain, pymain->argc);
+static void
+pymain_clear_configs(_PyMain *pymain)
+{
+ _PyMainInterpreterConfig_Clear(&pymain->config);
+
+ /* Clear core config with the memory allocator
+ used by pymain_read_conf() */
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
_PyCoreConfig_Clear(&pymain->core_config);
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
}
-/* Clear Python ojects */
static void
-pymain_clear_python(_PyMain *pymain)
+pymain_free_python(_PyMain *pymain)
{
Py_CLEAR(pymain->main_importer_path);
-
_PyMainInterpreterConfig_Clear(&pymain->config);
+
+#ifdef __INSURE__
+ /* Insure++ is a memory analysis tool that aids in discovering
+ * memory leaks and other memory problems. On Python exit, the
+ * interned string dictionaries are flagged as being in use at exit
+ * (which it is). Under normal circumstances, this is fine because
+ * the memory will be automatically reclaimed by the system. Under
+ * memory debugging, it's a huge source of useless noise, so we
+ * trade off slower shutdown for less distraction in the memory
+ * reports. -baw
+ */
+ _Py_ReleaseInternedUnicodeStrings();
+#endif /* __INSURE__ */
}
static void
-pymain_free(_PyMain *pymain)
+pymain_free_raw(_PyMain *pymain)
{
+ _PyImport_Fini2();
+
+ /* Free global variables which cannot be freed in Py_Finalize():
+ configuration options set before Py_Initialize() which should
+ remain valid after Py_Finalize(), since
+ Py_Initialize()-Py_Finalize() can be called multiple times. */
+ _PyPathConfig_Clear(&_Py_path_config);
+
/* Force the allocator used by pymain_read_conf() */
PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
- pymain_clear_python(pymain);
- pymain_clear_pymain(pymain);
- pymain_free_globals(pymain);
+ _PyCoreConfig_Clear(&pymain->core_config);
+ pymain_clear_cmdline(pymain);
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
}
+static void
+pymain_free(_PyMain *pymain)
+{
+ pymain_free_python(pymain);
+ pymain_free_raw(pymain);
+}
+
+
static int
pymain_run_main_from_importer(_PyMain *pymain)
{
@@ -645,7 +665,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain)
_PyOS_ResetGetOpt();
do {
int longindex = -1;
- int c = _PyOS_GetOpt(pymain->argc, pymain->argv, PROGRAM_OPTS,
+ int c = _PyOS_GetOpt(pymain->argc, cmdline->argv, PROGRAM_OPTS,
longoptions, &longindex);
if (c == EOF) {
break;
@@ -791,9 +811,9 @@ pymain_parse_cmdline_impl(_PyMain *pymain)
if (cmdline->command == NULL && cmdline->module == NULL
&& _PyOS_optind < pymain->argc
- && wcscmp(pymain->argv[_PyOS_optind], L"-") != 0)
+ && wcscmp(cmdline->argv[_PyOS_optind], L"-") != 0)
{
- cmdline->filename = pymain->argv[_PyOS_optind];
+ cmdline->filename = cmdline->argv[_PyOS_optind];
}
pymain->run_code = (cmdline->command != NULL || cmdline->filename != NULL
@@ -947,7 +967,7 @@ pymain_init_warnoptions(_PyMain *pymain)
if (pymain_add_warning_dev_mode(warnoptions, &pymain->core_config) < 0) {
goto error;
}
- if (pymain_add_warnings_optlist(warnoptions, &pymain->env_warning_options) < 0) {
+ if (pymain_add_warnings_optlist(warnoptions, &pymain->cmdline.env_warning_options) < 0) {
goto error;
}
if (pymain_add_warnings_optlist(warnoptions, &pymain->cmdline.warning_options) < 0) {
@@ -990,7 +1010,7 @@ pymain_warnings_envvar(_PyMain *pymain)
warning != NULL;
warning = wcstok_s(NULL, L",", &context)) {
- if (pymain_optlist_append(pymain, &pymain->env_warning_options,
+ if (pymain_optlist_append(pymain, &pymain->cmdline.env_warning_options,
warning) < 0) {
PyMem_RawFree(buf);
return -1;
@@ -1020,7 +1040,7 @@ pymain_warnings_envvar(_PyMain *pymain)
SET_DECODE_ERROR("PYTHONWARNINGS environment variable", len);
return -1;
}
- if (pymain_optlist_append(pymain, &pymain->env_warning_options,
+ if (pymain_optlist_append(pymain, &pymain->cmdline.env_warning_options,
warning) < 0) {
PyMem_RawFree(warning);
return -1;
@@ -1142,7 +1162,7 @@ pymain_get_program_name(_PyMain *pymain)
{
if (pymain->core_config.program_name == NULL) {
/* Use argv[0] by default */
- pymain->core_config.program_name = pymain_wstrdup(pymain, pymain->argv[0]);
+ pymain->core_config.program_name = pymain_wstrdup(pymain, pymain->cmdline.argv[0]);
if (pymain->core_config.program_name == NULL) {
return -1;
}
@@ -1170,66 +1190,102 @@ pymain_header(_PyMain *pymain)
}
+static wchar_t**
+copy_argv(int argc, wchar_t **argv)
+{
+ assert(argc >= 0 && argv != NULL);
+ size_t size = argc * sizeof(argv[0]);
+ wchar_t **argv_copy = PyMem_RawMalloc(size);
+ for (int i=0; i < argc; i++) {
+ wchar_t* arg = _PyMem_RawWcsdup(argv[i]);
+ if (arg == NULL) {
+ clear_argv(i, argv);
+ return NULL;
+ }
+ argv_copy[i] = arg;
+ }
+ return argv_copy;
+}
+
+
static int
-pymain_init_argv(_PyMain *pymain)
+pymain_init_core_argv(_PyMain *pymain)
{
- int argc = pymain->sys_argc;
- wchar_t** argv = pymain->sys_argv;
+ _Py_CommandLineDetails *cmdline = &pymain->cmdline;
+
+ /* Copy argv to be able to modify it (to force -c/-m) */
+ int argc = pymain->argc - _PyOS_optind;
+ wchar_t **argv;
- if (argc <= 0 || pymain->sys_argv == NULL) {
+ if (argc <= 0 || cmdline->argv == NULL) {
/* Ensure at least one (empty) argument is seen */
static wchar_t *empty_argv[1] = {L""};
- argv = empty_argv;
argc = 1;
+ argv = copy_argv(1, empty_argv);
+ }
+ else {
+ argv = copy_argv(argc, &cmdline->argv[_PyOS_optind]);
}
- PyObject *list = PyList_New(argc);
- if (list == NULL) {
+ if (argv == NULL) {
+ pymain->err = _Py_INIT_NO_MEMORY();
return -1;
}
- for (int i = 0; i < argc; i++) {
- PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
- if (v == NULL) {
- Py_DECREF(list);
+ wchar_t *arg0 = NULL;
+ if (cmdline->command != NULL) {
+ /* Force sys.argv[0] = '-c' */
+ arg0 = L"-c";
+ }
+ else if (cmdline->module != NULL) {
+ /* Force sys.argv[0] = '-m'*/
+ arg0 = L"-m";
+ }
+ if (arg0 != NULL) {
+ arg0 = _PyMem_RawWcsdup(arg0);
+ if (arg0 == NULL) {
+ clear_argv(argc, argv);
+ pymain->err = _Py_INIT_NO_MEMORY();
return -1;
}
- PyList_SET_ITEM(list, i, v);
+ PyMem_RawFree(argv[0]);
+ argv[0] = arg0;
}
- pymain->config.argv = list;
+ pymain->core_config.argc = argc;
+ pymain->core_config.argv = argv;
return 0;
}
static int
-pymain_init_sys_argv(_PyMain *pymain)
+config_init_argv(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_config)
{
- _Py_CommandLineDetails *cmdline = &pymain->cmdline;
+ assert(config->argv == NULL);
- if (cmdline->command != NULL || cmdline->module != NULL) {
- /* Backup _PyOS_optind */
- _PyOS_optind--;
+ if (core_config->argc < 0) {
+ return 0;
}
- /* Copy argv to be able to modify it (to force -c/-m) */
- pymain->sys_argc = pymain->argc - _PyOS_optind;
- size_t size = pymain->sys_argc * sizeof(pymain->argv[0]);
- pymain->sys_argv = PyMem_RawMalloc(size);
- if (pymain->sys_argv == NULL) {
- pymain->err = _Py_INIT_NO_MEMORY();
+ int argc = core_config->argc;
+ wchar_t** argv = core_config->argv;
+ assert(argc >= 1 && argv != NULL);
+
+ PyObject *list = PyList_New(argc);
+ if (list == NULL) {
return -1;
}
- memcpy(pymain->sys_argv, &pymain->argv[_PyOS_optind], size);
- if (cmdline->command != NULL) {
- /* Force sys.argv[0] = '-c' */
- pymain->sys_argv[0] = L"-c";
- }
- else if (cmdline->module != NULL) {
- /* Force sys.argv[0] = '-m'*/
- pymain->sys_argv[0] = L"-m";
+ for (int i = 0; i < argc; i++) {
+ PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
+ if (v == NULL) {
+ Py_DECREF(list);
+ return -1;
+ }
+ PyList_SET_ITEM(list, i, v);
}
+
+ config->argv = list;
return 0;
}
@@ -1254,7 +1310,7 @@ pymain_update_sys_path(_PyMain *pymain)
return -1;
}
- PyObject *path0 = _PyPathConfig_ComputeArgv0(pymain->sys_argc, pymain->sys_argv);
+ PyObject *path0 = _PyPathConfig_ComputeArgv0(pymain->core_config.argc, pymain->core_config.argv);
if (path0 == NULL) {
pymain->err = _Py_INIT_NO_MEMORY();
return -1;
@@ -1374,7 +1430,7 @@ pymain_open_filename(_PyMain *pymain)
else
cfilename = "<unprintable file name>";
fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
- pymain->argv[0], cfilename, err, strerror(err));
+ cmdline->argv[0], cfilename, err, strerror(err));
PyMem_Free(cfilename_buffer);
pymain->status = 2;
return NULL;
@@ -1397,7 +1453,7 @@ pymain_open_filename(_PyMain *pymain)
S_ISDIR(sb.st_mode)) {
fprintf(stderr,
"%ls: '%ls' is a directory, cannot continue\n",
- pymain->argv[0], cmdline->filename);
+ cmdline->argv[0], cmdline->filename);
fclose(fp);
pymain->status = 1;
return NULL;
@@ -1474,11 +1530,16 @@ pymain_parse_cmdline(_PyMain *pymain)
return -1;
}
if (res) {
- pymain_usage(1, pymain->argv[0]);
+ pymain_usage(1, pymain->cmdline.argv[0]);
pymain->status = 2;
return 1;
}
+ if (pymain->cmdline.command != NULL || pymain->cmdline.module != NULL) {
+ /* Backup _PyOS_optind */
+ _PyOS_optind--;
+ }
+
return 0;
}
@@ -1912,7 +1973,7 @@ pymain_read_conf_impl(_PyMain *pymain)
return -1;
}
- if (pymain_init_sys_argv(pymain) < 0) {
+ if (pymain_init_core_argv(pymain) < 0) {
return -1;
}
@@ -1960,10 +2021,8 @@ pymain_read_conf(_PyMain *pymain)
goto done;
}
- if (pymain->use_bytes_argv) {
- if (pymain_decode_bytes_argv(pymain) < 0) {
- goto done;
- }
+ if (pymain_init_cmdline_argv(pymain) < 0) {
+ goto done;
}
res = pymain_read_conf_impl(pymain);
@@ -2008,7 +2067,8 @@ pymain_read_conf(_PyMain *pymain)
pymain_read_conf_impl(). */
Py_UTF8Mode = pymain->core_config.utf8_mode;
Py_IgnoreEnvironmentFlag = init_ignore_env;
- pymain_clear_pymain(pymain);
+ _PyCoreConfig_Clear(&pymain->core_config);
+ pymain_clear_cmdline(pymain);
pymain_get_global_config(pymain);
/* The encoding changed: read again the configuration
@@ -2089,6 +2149,12 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
CLEAR(config->home);
CLEAR(config->program_name);
#undef CLEAR
+
+ if (config->argc >= 0) {
+ clear_argv(config->argc, config->argv);
+ config->argc = -1;
+ config->argv = NULL;
+ }
}
@@ -2098,6 +2164,16 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
_PyCoreConfig_Clear(config);
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
+#define COPY_STR_ATTR(ATTR) \
+ do { \
+ if (config2->ATTR != NULL) { \
+ config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
+ if (config->ATTR == NULL) { \
+ return -1; \
+ } \
+ } \
+ } while (0)
+
COPY_ATTR(ignore_environment);
COPY_ATTR(use_hash_seed);
COPY_ATTR(hash_seed);
@@ -2112,21 +2188,21 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
COPY_ATTR(dump_refs);
COPY_ATTR(malloc_stats);
COPY_ATTR(utf8_mode);
-#undef COPY_ATTR
-
-#define COPY_STR_ATTR(ATTR) \
- do { \
- if (config2->ATTR != NULL) { \
- config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \
- if (config->ATTR == NULL) { \
- return -1; \
- } \
- } \
- } while (0)
COPY_STR_ATTR(module_search_path_env);
COPY_STR_ATTR(home);
COPY_STR_ATTR(program_name);
+
+ if (config2->argc >= 0) {
+ wchar_t **argv = copy_argv(config2->argc, config2->argv);
+ if (argv == NULL) {
+ return -1;
+ }
+ config->argv = argv;
+ }
+ COPY_ATTR(argc);
+
+#undef COPY_ATTR
#undef COPY_STR_ATTR
return 0;
}
@@ -2241,13 +2317,17 @@ config_create_path_list(const wchar_t *path, wchar_t delim)
_PyInitError
-_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, _PyCoreConfig *core_config)
+_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_config)
{
_PyInitError err = _PyPathConfig_Init(core_config);
if (_Py_INIT_FAILED(err)) {
return err;
}
+ if (config_init_argv(config, core_config) < 0) {
+ return _Py_INIT_ERR("failed to create sys.argv");
+ }
+
/* Signal handlers are installed by default */
if (config->install_signal_handlers < 0) {
config->install_signal_handlers = 1;
@@ -2324,10 +2404,6 @@ pymain_init_python_main(_PyMain *pymain)
pymain->err = _Py_INIT_NO_MEMORY();
return -1;
}
- if (pymain_init_argv(pymain) < 0) {
- pymain->err = _Py_INIT_ERR("failed to create sys.argv");
- return -1;
- }
_PyInitError err = _PyMainInterpreterConfig_Read(&pymain->config,
&pymain->core_config);
@@ -2378,9 +2454,11 @@ pymain_run_python(_PyMain *pymain)
}
-static int
+static void
pymain_init(_PyMain *pymain)
{
+ memset(&pymain->cmdline, 0, sizeof(pymain->cmdline));
+
/* 754 requires that FP exceptions run in "no stop" mode by default,
* and until C vendors implement C99's ways to control FP exceptions,
* Python requires non-stop mode. Alas, some platforms enable FP
@@ -2390,23 +2468,18 @@ pymain_init(_PyMain *pymain)
fedisableexcept(FE_OVERFLOW);
#endif
- pymain->err = _PyRuntime_Initialize();
- if (_Py_INIT_FAILED(pymain->err)) {
- return -1;
- }
-
pymain->core_config._disable_importlib = 0;
pymain->config.install_signal_handlers = 1;
pymain_get_global_config(pymain);
- return 0;
}
static int
pymain_impl(_PyMain *pymain)
{
- if (pymain_init(pymain) < 0) {
+ pymain->err = _PyRuntime_Initialize();
+ if (_Py_INIT_FAILED(pymain->err)) {
return -1;
}
@@ -2423,7 +2496,7 @@ pymain_impl(_PyMain *pymain)
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
if (cmdline->print_help) {
- pymain_usage(0, pymain->argv[0]);
+ pymain_usage(0, cmdline->argv[0]);
return 0;
}
@@ -2433,8 +2506,9 @@ pymain_impl(_PyMain *pymain)
return 0;
}
- orig_argc = pymain->argc; /* For Py_GetArgcArgv() */
- orig_argv = pymain->argv;
+ /* For Py_GetArgcArgv(). Cleared by pymain_free(). */
+ orig_argc = pymain->argc;
+ orig_argv = cmdline->argv;
res = pymain_init_python_core(pymain);
if (res < 0) {
@@ -2446,9 +2520,9 @@ pymain_impl(_PyMain *pymain)
return -1;
}
- pymain_run_python(pymain);
+ pymain_clear_configs(pymain);
- pymain_clear_python(pymain);
+ pymain_run_python(pymain);
if (Py_FinalizeEx() < 0) {
/* Value unlikely to be confused with a non-error exit status or
@@ -2462,16 +2536,13 @@ pymain_impl(_PyMain *pymain)
static int
pymain_main(_PyMain *pymain)
{
- memset(&pymain->cmdline, 0, sizeof(pymain->cmdline));
+ pymain_init(pymain);
if (pymain_impl(pymain) < 0) {
_Py_FatalInitError(pymain->err);
}
pymain_free(pymain);
- orig_argc = 0;
- orig_argv = NULL;
-
return pymain->status;
}
@@ -2480,8 +2551,9 @@ int
Py_Main(int argc, wchar_t **argv)
{
_PyMain pymain = _PyMain_INIT;
+ pymain.use_bytes_argv = 0;
pymain.argc = argc;
- pymain.argv = argv;
+ pymain.wchar_argv = argv;
return pymain_main(&pymain);
}
@@ -2491,8 +2563,8 @@ int
_Py_UnixMain(int argc, char **argv)
{
_PyMain pymain = _PyMain_INIT;
- pymain.argc = argc;
pymain.use_bytes_argv = 1;
+ pymain.argc = argc;
pymain.bytes_argv = argv;
return pymain_main(&pymain);