@@ -434,14 +434,11 @@ typedef struct {
434
434
435
435
/* .cmdline is initialized to zeros */
436
436
#define _PyMain_INIT \
437
- {.status = 0, \
438
- .cf = {.cf_flags = 0}, \
439
- .core_config = _PyCoreConfig_INIT, \
437
+ {.core_config = _PyCoreConfig_INIT, \
440
438
.config = _PyMainInterpreterConfig_INIT, \
441
- .main_importer_path = NULL, \
442
439
.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 */
445
442
446
443
447
444
static void
@@ -738,6 +735,9 @@ pymain_parse_cmdline_impl(_PyMain *pymain)
738
735
cmdline -> filename = pymain -> argv [_PyOS_optind ];
739
736
}
740
737
738
+ /* -c and -m options are exclusive */
739
+ assert (!(cmdline -> command != NULL && cmdline -> module != NULL ));
740
+
741
741
return 0 ;
742
742
}
743
743
@@ -1082,22 +1082,34 @@ pymain_header(_PyMain *pymain)
1082
1082
}
1083
1083
1084
1084
1085
- static void
1086
- pymain_set_argv (_PyMain * pymain )
1085
+ static int
1086
+ pymain_set_sys_argv (_PyMain * pymain )
1087
1087
{
1088
1088
_Py_CommandLineDetails * cmdline = & pymain -> cmdline ;
1089
1089
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 */
1093
1092
_PyOS_optind -- ;
1094
- pymain -> argv [_PyOS_optind ] = L"-c" ;
1095
1093
}
1096
1094
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" ;
1101
1113
}
1102
1114
1103
1115
int update_path ;
@@ -1108,9 +1120,18 @@ pymain_set_argv(_PyMain *pymain)
1108
1120
/* Use config settings to decide whether or not to update sys.path[0] */
1109
1121
update_path = (Py_IsolatedFlag == 0 );
1110
1122
}
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 ;
1114
1135
}
1115
1136
1116
1137
@@ -1604,7 +1625,7 @@ pymain_init_utf8_mode(_PyMain *pymain)
1604
1625
}
1605
1626
#endif
1606
1627
1607
- wchar_t * xopt = pymain_get_xoption (pymain , L"utf8" );
1628
+ const wchar_t * xopt = pymain_get_xoption (pymain , L"utf8" );
1608
1629
if (xopt ) {
1609
1630
wchar_t * sep = wcschr (xopt , L'=' );
1610
1631
if (sep ) {
@@ -1626,7 +1647,7 @@ pymain_init_utf8_mode(_PyMain *pymain)
1626
1647
return 0 ;
1627
1648
}
1628
1649
1629
- char * opt = pymain_get_env_var ("PYTHONUTF8" );
1650
+ const char * opt = pymain_get_env_var ("PYTHONUTF8" );
1630
1651
if (opt ) {
1631
1652
if (strcmp (opt , "1" ) == 0 ) {
1632
1653
core_config -> utf8_mode = 1 ;
@@ -1788,6 +1809,22 @@ pymain_init_python(_PyMain *pymain)
1788
1809
if (pymain_init_main_interpreter (pymain )) {
1789
1810
return -1 ;
1790
1811
}
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
+ }
1791
1828
return 0 ;
1792
1829
}
1793
1830
@@ -1800,12 +1837,6 @@ pymain_run_python(_PyMain *pymain)
1800
1837
pymain_header (pymain );
1801
1838
pymain_import_readline (pymain );
1802
1839
1803
- if (cmdline -> filename != NULL ) {
1804
- pymain -> main_importer_path = pymain_get_importer (cmdline -> filename );
1805
- }
1806
-
1807
- pymain_set_argv (pymain );
1808
-
1809
1840
if (cmdline -> command ) {
1810
1841
pymain -> status = pymain_run_command (cmdline -> command , & pymain -> cf );
1811
1842
}
@@ -1868,7 +1899,6 @@ pymain_impl(_PyMain *pymain)
1868
1899
other special meaning */
1869
1900
pymain -> status = 120 ;
1870
1901
}
1871
-
1872
1902
return 0 ;
1873
1903
}
1874
1904
0 commit comments