@@ -410,6 +410,13 @@ typedef struct {
410
410
#endif
411
411
} _Py_CommandLineDetails ;
412
412
413
+ /* FIXME: temporary structure until sys module configuration can be moved
414
+ into _PyMainInterpreterConfig */
415
+ typedef struct {
416
+ PyObject * argv ; /* sys.argv list */
417
+ PyObject * path0 ; /* path0: if set, it is prepended to sys.path */
418
+ } _PySysConfig ;
419
+
413
420
/* Structure used by Py_Main() to pass data to subfunctions */
414
421
typedef struct {
415
422
/* Exit status ("exit code") */
@@ -419,6 +426,7 @@ typedef struct {
419
426
int stdin_is_interactive ;
420
427
_PyCoreConfig core_config ;
421
428
_PyMainInterpreterConfig config ;
429
+ _PySysConfig sys_config ;
422
430
_Py_CommandLineDetails cmdline ;
423
431
PyObject * main_importer_path ;
424
432
/* non-zero if filename, command (-c) or module (-m) is set
@@ -492,6 +500,8 @@ pymain_free_pymain(_PyMain *pymain)
492
500
pymain_optlist_clear (& pymain -> env_warning_options );
493
501
Py_CLEAR (pymain -> main_importer_path );
494
502
503
+ Py_CLEAR (pymain -> sys_config .argv );
504
+ Py_CLEAR (pymain -> sys_config .path0 );
495
505
}
496
506
497
507
static void
@@ -510,26 +520,20 @@ pymain_free(_PyMain *pymain)
510
520
static int
511
521
pymain_run_main_from_importer (_PyMain * pymain )
512
522
{
513
- PyObject * sys_path0 = pymain -> main_importer_path ;
514
- PyObject * sys_path ;
515
- int sts ;
516
-
517
523
/* Assume sys_path0 has already been checked by pymain_get_importer(),
518
524
* so put it in sys.path[0] and import __main__ */
519
- sys_path = PySys_GetObject ("path" );
525
+ PyObject * sys_path = PySys_GetObject ("path" );
520
526
if (sys_path == NULL ) {
521
527
PyErr_SetString (PyExc_RuntimeError , "unable to get sys.path" );
522
528
goto error ;
523
529
}
524
530
525
- sts = PyList_Insert (sys_path , 0 , sys_path0 );
526
- if (sts ) {
527
- sys_path0 = NULL ;
531
+ if (PyList_Insert (sys_path , 0 , pymain -> main_importer_path )) {
528
532
goto error ;
529
533
}
530
534
531
- sts = pymain_run_module (L"__main__" , 0 );
532
- return sts != 0 ;
535
+ int sts = pymain_run_module (L"__main__" , 0 );
536
+ return ( sts != 0 ) ;
533
537
534
538
error :
535
539
Py_CLEAR (pymain -> main_importer_path );
@@ -1082,8 +1086,36 @@ pymain_header(_PyMain *pymain)
1082
1086
}
1083
1087
1084
1088
1089
+ static PyObject *
1090
+ pymain_create_argv_list (int argc , wchar_t * * argv )
1091
+ {
1092
+ if (argc <= 0 || argv == NULL ) {
1093
+ /* Ensure at least one (empty) argument is seen */
1094
+ static wchar_t * empty_argv [1 ] = {L"" };
1095
+ argv = empty_argv ;
1096
+ argc = 1 ;
1097
+ }
1098
+
1099
+ PyObject * av = PyList_New (argc );
1100
+ if (av == NULL ) {
1101
+ return NULL ;
1102
+ }
1103
+
1104
+ for (int i = 0 ; i < argc ; i ++ ) {
1105
+ PyObject * v = PyUnicode_FromWideChar (argv [i ], -1 );
1106
+ if (v == NULL ) {
1107
+ Py_DECREF (av );
1108
+ return NULL ;
1109
+ }
1110
+ PyList_SET_ITEM (av , i , v );
1111
+ }
1112
+ return av ;
1113
+ }
1114
+
1115
+
1116
+ /* Create sys.argv list and maybe also path0 */
1085
1117
static int
1086
- pymain_set_sys_argv (_PyMain * pymain )
1118
+ pymain_compute_argv (_PyMain * pymain )
1087
1119
{
1088
1120
_Py_CommandLineDetails * cmdline = & pymain -> cmdline ;
1089
1121
@@ -1112,6 +1144,14 @@ pymain_set_sys_argv(_PyMain *pymain)
1112
1144
argv2 [0 ] = L"-m" ;
1113
1145
}
1114
1146
1147
+ /* Create sys.argv list */
1148
+ pymain -> sys_config .argv = pymain_create_argv_list (argc2 , argv2 );
1149
+ if (pymain -> sys_config .argv == NULL ) {
1150
+ pymain -> err = _Py_INIT_ERR ("failed to create sys.argv" );
1151
+ goto error ;
1152
+ }
1153
+
1154
+ /* Need to update sys.path[0]? */
1115
1155
int update_path ;
1116
1156
if (pymain -> main_importer_path != NULL ) {
1117
1157
/* Let pymain_run_main_from_importer() adjust sys.path[0] later */
@@ -1121,16 +1161,48 @@ pymain_set_sys_argv(_PyMain *pymain)
1121
1161
update_path = (Py_IsolatedFlag == 0 );
1122
1162
}
1123
1163
1124
- /* Set sys.argv. If '-c' and '-m' options are not used in the command line
1164
+ /* If '-c' and '-m' options are not used in the command line
1125
1165
and update_path is non-zero, prepend argv[0] to sys.path. If argv[0] is
1126
1166
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 ;
1167
+ if (update_path ) {
1168
+ pymain -> sys_config .path0 = _PyPathConfig_ComputeArgv0 (argc2 , argv2 );
1169
+ if (pymain -> sys_config .path0 == NULL ) {
1170
+ pymain -> err = _Py_INIT_NO_MEMORY ();
1171
+ goto error ;
1172
+ }
1173
+ }
1174
+ PyMem_RawFree (argv2 );
1175
+ return 0 ;
1176
+
1177
+ error :
1178
+ return -1 ;
1179
+ }
1180
+
1181
+ static int
1182
+ pymain_set_sys_argv (_PyMain * pymain )
1183
+ {
1184
+ /* Set sys.argv */
1185
+ if (PySys_SetObject ("argv" , pymain -> sys_config .argv ) != 0 ) {
1186
+ pymain -> err = _Py_INIT_ERR ("can't assign sys.argv" );
1130
1187
return -1 ;
1131
1188
}
1189
+ Py_CLEAR (pymain -> sys_config .argv );
1190
+
1191
+ if (pymain -> sys_config .path0 != NULL ) {
1192
+ /* Prepend path0 to sys.path */
1193
+ PyObject * sys_path = PySys_GetObject ("path" );
1194
+ if (sys_path == NULL ) {
1195
+ pymain -> err = _Py_INIT_ERR ("can't get sys.path" );
1196
+ return -1 ;
1197
+ }
1198
+
1199
+ if (PyList_Insert (sys_path , 0 , pymain -> sys_config .path0 ) < 0 ) {
1200
+ pymain -> err = _Py_INIT_ERR ("sys.path.insert(0, path0) failed" );
1201
+ return -1 ;
1202
+ }
1203
+ Py_CLEAR (pymain -> sys_config .path0 );
1204
+ }
1132
1205
1133
- PyMem_RawFree (argv2 );
1134
1206
return 0 ;
1135
1207
}
1136
1208
@@ -1822,6 +1894,9 @@ pymain_init_python(_PyMain *pymain)
1822
1894
Currently, PySys_SetArgvEx() can still modify sys.path and so must be
1823
1895
called after _Py_InitializeMainInterpreter() which calls
1824
1896
_PyPathConfig_Init(). */
1897
+ if (pymain_compute_argv (pymain ) < 0 ) {
1898
+ return -1 ;
1899
+ }
1825
1900
if (pymain_set_sys_argv (pymain ) < 0 ) {
1826
1901
return -1 ;
1827
1902
}
0 commit comments