@@ -434,14 +434,11 @@ typedef struct {
434434
435435/* .cmdline is initialized to zeros */
436436#define _PyMain_INIT \
437- {.status = 0, \
438- .cf = {.cf_flags = 0}, \
439- .core_config = _PyCoreConfig_INIT, \
437+ {.core_config = _PyCoreConfig_INIT, \
440438 .config = _PyMainInterpreterConfig_INIT, \
441- .main_importer_path = NULL, \
442439 .run_code = -1, \
443- .err = _Py_INIT_OK(), \
444- .env_warning_options = {0, NULL}}
440+ .err = _Py_INIT_OK()}
441+ /* Note: _PyMain_INIT sets other fields to 0/ NULL */
445442
446443
447444static void
@@ -738,6 +735,9 @@ pymain_parse_cmdline_impl(_PyMain *pymain)
738735 cmdline -> filename = pymain -> argv [_PyOS_optind ];
739736 }
740737
738+ /* -c and -m options are exclusive */
739+ assert (!(cmdline -> command != NULL && cmdline -> module != NULL ));
740+
741741 return 0 ;
742742}
743743
@@ -1082,22 +1082,34 @@ pymain_header(_PyMain *pymain)
10821082}
10831083
10841084
1085- static void
1086- pymain_set_argv (_PyMain * pymain )
1085+ static int
1086+ pymain_set_sys_argv (_PyMain * pymain )
10871087{
10881088 _Py_CommandLineDetails * cmdline = & pymain -> cmdline ;
10891089
1090- /* TODO: Move this to _Py_InitializeMainInterpreter */
1091- if (cmdline -> command != NULL ) {
1092- /* Backup _PyOS_optind and force sys.argv[0] = '-c' */
1090+ if (cmdline -> command != NULL || cmdline -> module != NULL ) {
1091+ /* Backup _PyOS_optind */
10931092 _PyOS_optind -- ;
1094- pymain -> argv [_PyOS_optind ] = L"-c" ;
10951093 }
10961094
1097- if (cmdline -> module != NULL ) {
1098- /* Backup _PyOS_optind and force sys.argv[0] = '-m'*/
1099- _PyOS_optind -- ;
1100- pymain -> argv [_PyOS_optind ] = L"-m" ;
1095+ /* Copy argv to be able to modify it (to force -c/-m) */
1096+ int argc2 = pymain -> argc - _PyOS_optind ;
1097+ size_t size = argc2 * sizeof (pymain -> argv [0 ]);
1098+ wchar_t * * argv2 = PyMem_RawMalloc (size );
1099+ if (argv2 == NULL ) {
1100+ pymain -> err = _Py_INIT_NO_MEMORY ();
1101+ return -1 ;
1102+ }
1103+ memcpy (argv2 , & pymain -> argv [_PyOS_optind ], size );
1104+
1105+ /* TODO: Move this to _Py_InitializeMainInterpreter */
1106+ if (cmdline -> command != NULL ) {
1107+ /* Force sys.argv[0] = '-c' */
1108+ argv2 [0 ] = L"-c" ;
1109+ }
1110+ else if (cmdline -> module != NULL ) {
1111+ /* Force sys.argv[0] = '-m'*/
1112+ argv2 [0 ] = L"-m" ;
11011113 }
11021114
11031115 int update_path ;
@@ -1108,9 +1120,18 @@ pymain_set_argv(_PyMain *pymain)
11081120 /* Use config settings to decide whether or not to update sys.path[0] */
11091121 update_path = (Py_IsolatedFlag == 0 );
11101122 }
1111- PySys_SetArgvEx (pymain -> argc - _PyOS_optind ,
1112- pymain -> argv + _PyOS_optind ,
1113- update_path );
1123+
1124+ /* Set sys.argv. If '-c' and '-m' options are not used in the command line
1125+ and update_path is non-zero, prepend argv[0] to sys.path. If argv[0] is
1126+ a symlink, use the real path. */
1127+ _PyInitError err = _PySys_SetArgvWithError (argc2 , argv2 , update_path );
1128+ if (_Py_INIT_FAILED (err )) {
1129+ pymain -> err = err ;
1130+ return -1 ;
1131+ }
1132+
1133+ PyMem_RawFree (argv2 );
1134+ return 0 ;
11141135}
11151136
11161137
@@ -1604,7 +1625,7 @@ pymain_init_utf8_mode(_PyMain *pymain)
16041625 }
16051626#endif
16061627
1607- wchar_t * xopt = pymain_get_xoption (pymain , L"utf8" );
1628+ const wchar_t * xopt = pymain_get_xoption (pymain , L"utf8" );
16081629 if (xopt ) {
16091630 wchar_t * sep = wcschr (xopt , L'=' );
16101631 if (sep ) {
@@ -1626,7 +1647,7 @@ pymain_init_utf8_mode(_PyMain *pymain)
16261647 return 0 ;
16271648 }
16281649
1629- char * opt = pymain_get_env_var ("PYTHONUTF8" );
1650+ const char * opt = pymain_get_env_var ("PYTHONUTF8" );
16301651 if (opt ) {
16311652 if (strcmp (opt , "1" ) == 0 ) {
16321653 core_config -> utf8_mode = 1 ;
@@ -1788,6 +1809,22 @@ pymain_init_python(_PyMain *pymain)
17881809 if (pymain_init_main_interpreter (pymain )) {
17891810 return -1 ;
17901811 }
1812+
1813+ if (pymain -> cmdline .filename != NULL ) {
1814+ /* If filename is a package (ex: directory or ZIP file) which contains
1815+ __main__.py, main_importer_path is set to filename and will be
1816+ prepended to sys.path by pymain_run_main_from_importer(). Otherwise,
1817+ main_importer_path is set to NULL. */
1818+ pymain -> main_importer_path = pymain_get_importer (pymain -> cmdline .filename );
1819+ }
1820+
1821+ /* FIXME: put argv into _PyMainInterpreterConfig.
1822+ Currently, PySys_SetArgvEx() can still modify sys.path and so must be
1823+ called after _Py_InitializeMainInterpreter() which calls
1824+ _PyPathConfig_Init(). */
1825+ if (pymain_set_sys_argv (pymain ) < 0 ) {
1826+ return -1 ;
1827+ }
17911828 return 0 ;
17921829}
17931830
@@ -1800,12 +1837,6 @@ pymain_run_python(_PyMain *pymain)
18001837 pymain_header (pymain );
18011838 pymain_import_readline (pymain );
18021839
1803- if (cmdline -> filename != NULL ) {
1804- pymain -> main_importer_path = pymain_get_importer (cmdline -> filename );
1805- }
1806-
1807- pymain_set_argv (pymain );
1808-
18091840 if (cmdline -> command ) {
18101841 pymain -> status = pymain_run_command (cmdline -> command , & pymain -> cf );
18111842 }
@@ -1868,7 +1899,6 @@ pymain_impl(_PyMain *pymain)
18681899 other special meaning */
18691900 pymain -> status = 120 ;
18701901 }
1871-
18721902 return 0 ;
18731903}
18741904
0 commit comments