summaryrefslogtreecommitdiffstats
path: root/Modules/main.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-12-15 00:46:02 (GMT)
committerGitHub <noreply@github.com>2017-12-15 00:46:02 (GMT)
commitda273412c4374de07a500e7f23f89a6bb7527398 (patch)
tree86f8e89fa317de8ab4d8f06166a934e6810cc3d3 /Modules/main.c
parent358e5e17a51ba00742bfaee4557a94c3c4179c22 (diff)
downloadcpython-da273412c4374de07a500e7f23f89a6bb7527398.zip
cpython-da273412c4374de07a500e7f23f89a6bb7527398.tar.gz
cpython-da273412c4374de07a500e7f23f89a6bb7527398.tar.bz2
bpo-32030: Add _PyCoreConfig_Copy() (#4874)
Each interpreter now has its core_config and main_config copy: * Add _PyCoreConfig_Copy() and _PyMainInterpreterConfig_Copy() * Move _PyCoreConfig_Read(), _PyCoreConfig_Clear() and _PyMainInterpreterConfig_Clear() from Python/pylifecycle.c to Modules/main.c * Fix _Py_InitializeEx_Private(): call _PyCoreConfig_ReadEnv() before _Py_InitializeCore()
Diffstat (limited to 'Modules/main.c')
-rw-r--r--Modules/main.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/Modules/main.c b/Modules/main.c
index e1a2f98..8c4219c 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -1914,6 +1914,154 @@ pymain_parse_cmdline_envvars(_PyMain *pymain)
}
+/* Read configuration settings from standard locations
+ *
+ * This function doesn't make any changes to the interpreter state - it
+ * merely populates any missing configuration settings. This allows an
+ * embedding application to completely override a config option by
+ * setting it before calling this function, or else modify the default
+ * setting before passing the fully populated config to Py_EndInitialization.
+ *
+ * More advanced selective initialization tricks are possible by calling
+ * this function multiple times with various preconfigured settings.
+ */
+
+_PyInitError
+_PyCoreConfig_Read(_PyCoreConfig *config)
+{
+ if (config->program_name == NULL) {
+#ifdef MS_WINDOWS
+ const wchar_t *program_name = L"python";
+#else
+ const wchar_t *program_name = L"python3";
+#endif
+ config->program_name = _PyMem_RawWcsdup(program_name);
+ if (config->program_name == NULL) {
+ return _Py_INIT_NO_MEMORY();
+ }
+ }
+
+ return _Py_INIT_OK();
+}
+
+
+void
+_PyCoreConfig_Clear(_PyCoreConfig *config)
+{
+#define CLEAR(ATTR) \
+ do { \
+ PyMem_RawFree(ATTR); \
+ ATTR = NULL; \
+ } while (0)
+
+ CLEAR(config->module_search_path_env);
+ CLEAR(config->home);
+ CLEAR(config->program_name);
+#undef CLEAR
+}
+
+
+int
+_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
+{
+ _PyCoreConfig_Clear(config);
+
+#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
+ COPY_ATTR(ignore_environment);
+ COPY_ATTR(use_hash_seed);
+ COPY_ATTR(hash_seed);
+ COPY_ATTR(_disable_importlib);
+ COPY_ATTR(allocator);
+ COPY_ATTR(dev_mode);
+ COPY_ATTR(faulthandler);
+ COPY_ATTR(tracemalloc);
+ COPY_ATTR(import_time);
+ COPY_ATTR(show_ref_count);
+ COPY_ATTR(show_alloc_count);
+ 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);
+#undef COPY_STR_ATTR
+ return 0;
+}
+
+
+void
+_PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)
+{
+ Py_CLEAR(config->argv);
+ Py_CLEAR(config->module_search_path);
+ Py_CLEAR(config->warnoptions);
+ Py_CLEAR(config->xoptions);
+}
+
+
+static PyObject*
+config_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) \
+ do { \
+ if (config2->ATTR != NULL) { \
+ config->ATTR = config_copy_attr(config2->ATTR); \
+ if (config->ATTR == NULL) { \
+ return -1; \
+ } \
+ } \
+ } while (0)
+
+ COPY_ATTR(argv);
+ COPY_ATTR(module_search_path);
+ COPY_ATTR(warnoptions);
+ COPY_ATTR(xoptions);
+#undef COPY_ATTR
+ return 0;
+}
+
+
+
+
static PyObject *
config_create_path_list(const wchar_t *path, wchar_t delim)
{