|
|
|
@ -31,255 +31,6 @@ |
|
|
|
extern "C" { |
|
|
|
#endif |
|
|
|
|
|
|
|
/* --- PyMainInterpreter ------------------------------------------ */ |
|
|
|
|
|
|
|
void |
|
|
|
_PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config) |
|
|
|
{ |
|
|
|
Py_CLEAR(config->argv); |
|
|
|
Py_CLEAR(config->executable); |
|
|
|
Py_CLEAR(config->prefix); |
|
|
|
Py_CLEAR(config->base_prefix); |
|
|
|
Py_CLEAR(config->exec_prefix); |
|
|
|
Py_CLEAR(config->base_exec_prefix); |
|
|
|
Py_CLEAR(config->warnoptions); |
|
|
|
Py_CLEAR(config->xoptions); |
|
|
|
Py_CLEAR(config->module_search_path); |
|
|
|
Py_CLEAR(config->pycache_prefix); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
mainconfig_add_xoption(PyObject *opts, const wchar_t *s) |
|
|
|
{ |
|
|
|
PyObject *name, *value; |
|
|
|
|
|
|
|
const wchar_t *name_end = wcschr(s, L'='); |
|
|
|
if (!name_end) { |
|
|
|
name = PyUnicode_FromWideChar(s, -1); |
|
|
|
value = Py_True; |
|
|
|
Py_INCREF(value); |
|
|
|
} |
|
|
|
else { |
|
|
|
name = PyUnicode_FromWideChar(s, name_end - s); |
|
|
|
value = PyUnicode_FromWideChar(name_end + 1, -1); |
|
|
|
} |
|
|
|
if (name == NULL || value == NULL) { |
|
|
|
goto error; |
|
|
|
} |
|
|
|
if (PyDict_SetItem(opts, name, value) < 0) { |
|
|
|
goto error; |
|
|
|
} |
|
|
|
Py_DECREF(name); |
|
|
|
Py_DECREF(value); |
|
|
|
return 0; |
|
|
|
|
|
|
|
error: |
|
|
|
Py_XDECREF(name); |
|
|
|
Py_XDECREF(value); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static PyObject* |
|
|
|
mainconfig_create_xoptions_dict(const _PyCoreConfig *config) |
|
|
|
{ |
|
|
|
Py_ssize_t nxoption = config->xoptions.length; |
|
|
|
wchar_t * const * xoptions = config->xoptions.items; |
|
|
|
PyObject *dict = PyDict_New(); |
|
|
|
if (dict == NULL) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
for (Py_ssize_t i=0; i < nxoption; i++) { |
|
|
|
const wchar_t *option = xoptions[i]; |
|
|
|
if (mainconfig_add_xoption(dict, option) < 0) { |
|
|
|
Py_DECREF(dict); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return dict; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static PyObject* |
|
|
|
mainconfig_copy_attr(PyObject *obj) |
|
|
|
{ |
|
|
|
if (PyUnicode_Check(obj)) { |
|
|
|
Py_INCREF(obj); |
|
|
|
return obj; |
|
|
|
} |
|
|
|
else if (PyList_Check(obj)) { |
|
|
|
return PyList_GetSlice(obj, 0, Py_SIZE(obj)); |
|
|
|
} |
|
|
|
else if (PyDict_Check(obj)) { |
|
|
|
/* The dict type is used for xoptions. Make the assumption that keys |
|
|
|
and values are immutables */ |
|
|
|
return PyDict_Copy(obj); |
|
|
|
} |
|
|
|
else { |
|
|
|
PyErr_Format(PyExc_TypeError, |
|
|
|
"cannot copy config attribute of type %.200s", |
|
|
|
Py_TYPE(obj)->tp_name); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
_PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config, |
|
|
|
const _PyMainInterpreterConfig *config2) |
|
|
|
{ |
|
|
|
_PyMainInterpreterConfig_Clear(config); |
|
|
|
|
|
|
|
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR |
|
|
|
#define COPY_OBJ_ATTR(ATTR) \ |
|
|
|
do { \ |
|
|
|
if (config2->ATTR != NULL) { \ |
|
|
|
config->ATTR = mainconfig_copy_attr(config2->ATTR); \ |
|
|
|
if (config->ATTR == NULL) { \ |
|
|
|
return -1; \ |
|
|
|
} \ |
|
|
|
} \ |
|
|
|
} while (0) |
|
|
|
|
|
|
|
COPY_ATTR(install_signal_handlers); |
|
|
|
COPY_OBJ_ATTR(argv); |
|
|
|
COPY_OBJ_ATTR(executable); |
|
|
|
COPY_OBJ_ATTR(prefix); |
|
|
|
COPY_OBJ_ATTR(base_prefix); |
|
|
|
COPY_OBJ_ATTR(exec_prefix); |
|
|
|
COPY_OBJ_ATTR(base_exec_prefix); |
|
|
|
COPY_OBJ_ATTR(warnoptions); |
|
|
|
COPY_OBJ_ATTR(xoptions); |
|
|
|
COPY_OBJ_ATTR(module_search_path); |
|
|
|
COPY_OBJ_ATTR(pycache_prefix); |
|
|
|
#undef COPY_ATTR |
|
|
|
#undef COPY_OBJ_ATTR |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
PyObject* |
|
|
|
_PyMainInterpreterConfig_AsDict(const _PyMainInterpreterConfig *config) |
|
|
|
{ |
|
|
|
PyObject *dict, *obj; |
|
|
|
int res; |
|
|
|
|
|
|
|
dict = PyDict_New(); |
|
|
|
if (dict == NULL) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
#define SET_ITEM_INT(ATTR) \ |
|
|
|
do { \ |
|
|
|
obj = PyLong_FromLong(config->ATTR); \ |
|
|
|
if (obj == NULL) { \ |
|
|
|
goto fail; \ |
|
|
|
} \ |
|
|
|
res = PyDict_SetItemString(dict, #ATTR, obj); \ |
|
|
|
Py_DECREF(obj); \ |
|
|
|
if (res < 0) { \ |
|
|
|
goto fail; \ |
|
|
|
} \ |
|
|
|
} while (0) |
|
|
|
|
|
|
|
#define SET_ITEM_OBJ(ATTR) \ |
|
|
|
do { \ |
|
|
|
obj = config->ATTR; \ |
|
|
|
if (obj == NULL) { \ |
|
|
|
obj = Py_None; \ |
|
|
|
} \ |
|
|
|
res = PyDict_SetItemString(dict, #ATTR, obj); \ |
|
|
|
if (res < 0) { \ |
|
|
|
goto fail; \ |
|
|
|
} \ |
|
|
|
} while (0) |
|
|
|
|
|
|
|
SET_ITEM_INT(install_signal_handlers); |
|
|
|
SET_ITEM_OBJ(argv); |
|
|
|
SET_ITEM_OBJ(executable); |
|
|
|
SET_ITEM_OBJ(prefix); |
|
|
|
SET_ITEM_OBJ(base_prefix); |
|
|
|
SET_ITEM_OBJ(exec_prefix); |
|
|
|
SET_ITEM_OBJ(base_exec_prefix); |
|
|
|
SET_ITEM_OBJ(warnoptions); |
|
|
|
SET_ITEM_OBJ(xoptions); |
|
|
|
SET_ITEM_OBJ(module_search_path); |
|
|
|
SET_ITEM_OBJ(pycache_prefix); |
|
|
|
|
|
|
|
return dict; |
|
|
|
|
|
|
|
fail: |
|
|
|
Py_DECREF(dict); |
|
|
|
return NULL; |
|
|
|
|
|
|
|
#undef SET_ITEM_OBJ |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_PyInitError |
|
|
|
_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config, |
|
|
|
const _PyCoreConfig *config) |
|
|
|
{ |
|
|
|
if (main_config->install_signal_handlers < 0) { |
|
|
|
main_config->install_signal_handlers = config->install_signal_handlers; |
|
|
|
} |
|
|
|
|
|
|
|
if (main_config->xoptions == NULL) { |
|
|
|
main_config->xoptions = mainconfig_create_xoptions_dict(config); |
|
|
|
if (main_config->xoptions == NULL) { |
|
|
|
return _Py_INIT_NO_MEMORY(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#define COPY_WSTR(ATTR) \ |
|
|
|
do { \ |
|
|
|
if (main_config->ATTR == NULL && config->ATTR != NULL) { \ |
|
|
|
main_config->ATTR = PyUnicode_FromWideChar(config->ATTR, -1); \ |
|
|
|
if (main_config->ATTR == NULL) { \ |
|
|
|
return _Py_INIT_NO_MEMORY(); \ |
|
|
|
} \ |
|
|
|
} \ |
|
|
|
} while (0) |
|
|
|
#define COPY_WSTRLIST(ATTR, LIST) \ |
|
|
|
do { \ |
|
|
|
if (ATTR == NULL) { \ |
|
|
|
ATTR = _PyWstrList_AsList(LIST); \ |
|
|
|
if (ATTR == NULL) { \ |
|
|
|
return _Py_INIT_NO_MEMORY(); \ |
|
|
|
} \ |
|
|
|
} \ |
|
|
|
} while (0) |
|
|
|
|
|
|
|
COPY_WSTRLIST(main_config->warnoptions, &config->warnoptions); |
|
|
|
COPY_WSTRLIST(main_config->argv, &config->argv); |
|
|
|
|
|
|
|
if (config->_install_importlib) { |
|
|
|
COPY_WSTR(executable); |
|
|
|
COPY_WSTR(prefix); |
|
|
|
COPY_WSTR(base_prefix); |
|
|
|
COPY_WSTR(exec_prefix); |
|
|
|
COPY_WSTR(base_exec_prefix); |
|
|
|
|
|
|
|
COPY_WSTRLIST(main_config->module_search_path, |
|
|
|
&config->module_search_paths); |
|
|
|
|
|
|
|
if (config->pycache_prefix != NULL) { |
|
|
|
COPY_WSTR(pycache_prefix); |
|
|
|
} else { |
|
|
|
main_config->pycache_prefix = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return _Py_INIT_OK(); |
|
|
|
#undef COPY_WSTR |
|
|
|
#undef COPY_WSTRLIST |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* --- pymain_init() ---------------------------------------------- */ |
|
|
|
|
|
|
|
static _PyInitError |
|
|
|
@ -315,25 +66,6 @@ pymain_init_coreconfig(_PyCoreConfig *config, const _PyArgv *args, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static _PyInitError |
|
|
|
pymain_init_python_main(PyInterpreterState *interp) |
|
|
|
{ |
|
|
|
_PyInitError err; |
|
|
|
|
|
|
|
_PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT; |
|
|
|
err = _PyMainInterpreterConfig_Read(&main_config, &interp->core_config); |
|
|
|
if (!_Py_INIT_FAILED(err)) { |
|
|
|
err = _Py_InitializeMainInterpreter(interp, &main_config); |
|
|
|
} |
|
|
|
_PyMainInterpreterConfig_Clear(&main_config); |
|
|
|
|
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
return _Py_INIT_OK(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static _PyInitError |
|
|
|
pymain_init(const _PyArgv *args, PyInterpreterState **interp_p) |
|
|
|
{ |
|
|
|
@ -365,7 +97,7 @@ pymain_init(const _PyArgv *args, PyInterpreterState **interp_p) |
|
|
|
return err; |
|
|
|
} |
|
|
|
|
|
|
|
err = pymain_init_python_main(*interp_p); |
|
|
|
err = _Py_InitializeMainInterpreter(*interp_p); |
|
|
|
if (_Py_INIT_FAILED(err)) { |
|
|
|
return err; |
|
|
|
} |
|
|
|
|