[Python-checkins] bpo-32030: Add _PyMainInterpreterConfig.warnoptions (#4855)

Victor Stinner webhook-mailer at python.org
Thu Dec 14 06:05:29 EST 2017


https://github.com/python/cpython/commit/374c6e178a7599aae46c857b17c6c8bc19dfe4c2
commit: 374c6e178a7599aae46c857b17c6c8bc19dfe4c2
branch: master
author: Victor Stinner <victor.stinner at gmail.com>
committer: GitHub <noreply at github.com>
date: 2017-12-14T12:05:26+01:00
summary:

bpo-32030: Add _PyMainInterpreterConfig.warnoptions (#4855)

Add warnoptions and xoptions fields to _PyMainInterpreterConfig.

files:
M Include/pystate.h
M Modules/main.c
M Python/pylifecycle.c

diff --git a/Include/pystate.h b/Include/pystate.h
index 9a26cc3909f..e8cf4134a8c 100644
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -59,6 +59,8 @@ typedef struct {
     int install_signal_handlers;
     PyObject *argv;                 /* sys.argv list, can be NULL */
     PyObject *module_search_path;   /* sys.path list */
+    PyObject *warnoptions;          /* sys.warnoptions list, can be NULL */
+    PyObject *xoptions;             /* sys._xoptions dict, can be NULL */
 } _PyMainInterpreterConfig;
 
 #define _PyMainInterpreterConfig_INIT \
diff --git a/Modules/main.c b/Modules/main.c
index 3f942fe067a..6db7e5f7088 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -752,29 +752,67 @@ pymain_parse_cmdline_impl(_PyMain *pymain)
 
 
 static int
-pymain_add_xoptions(_PyMain *pymain)
+pymain_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 int
+pymain_init_xoptions_dict(_PyMain *pymain)
 {
     _Py_OptList *options = &pymain->cmdline.xoptions;
+    PyObject *dict = PyDict_New();
+    if (dict == NULL) {
+        return -1;
+    }
+
     for (size_t i=0; i < options->len; i++) {
         wchar_t *option = options->options[i];
-        if (_PySys_AddXOptionWithError(option) < 0) {
-            pymain->err = _Py_INIT_NO_MEMORY();
+        if (pymain_add_xoption(dict, option) < 0) {
+            Py_DECREF(dict);
             return -1;
         }
     }
+
+    pymain->config.xoptions = dict;
     return 0;
 }
 
 
 static int
-pymain_add_warnings_optlist(_Py_OptList *warnings)
+pymain_add_warnings_optlist(PyObject *warnoptions, _Py_OptList *warnings)
 {
     for (size_t i = 0; i < warnings->len; i++) {
         PyObject *option = PyUnicode_FromWideChar(warnings->options[i], -1);
         if (option == NULL) {
             return -1;
         }
-        if (_PySys_AddWarnOptionWithError(option)) {
+        if (PyList_Append(warnoptions, option)) {
             Py_DECREF(option);
             return -1;
         }
@@ -785,14 +823,14 @@ pymain_add_warnings_optlist(_Py_OptList *warnings)
 
 
 static int
-pymain_add_warning_dev_mode(_PyCoreConfig *core_config)
+pymain_add_warning_dev_mode(PyObject *warnoptions, _PyCoreConfig *core_config)
 {
     if (core_config->dev_mode) {
         PyObject *option = PyUnicode_FromString("default");
         if (option == NULL) {
             return -1;
         }
-        if (_PySys_AddWarnOptionWithError(option)) {
+        if (PyList_Append(warnoptions, option)) {
             Py_DECREF(option);
             return -1;
         }
@@ -803,33 +841,38 @@ pymain_add_warning_dev_mode(_PyCoreConfig *core_config)
 
 
 static int
-pymain_add_warning_bytes_flag(int bytes_warning_flag)
+pymain_add_warning_bytes_flag(PyObject *warnoptions, int bytes_warning_flag)
 {
     /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
      * don't even try to emit a warning, so we skip setting the filter in that
      * case.
      */
-    if (bytes_warning_flag) {
-        const char *filter = (bytes_warning_flag > 1) ? "error::BytesWarning":
-                                                        "default::BytesWarning";
-        PyObject *option = PyUnicode_FromString(filter);
-        if (option == NULL) {
-            return -1;
-        }
-        if (_PySys_AddWarnOptionWithError(option)) {
-            Py_DECREF(option);
-            return -1;
-        }
+    if (!bytes_warning_flag) {
+        return 0;
+    }
+
+    const char *filter = (bytes_warning_flag > 1) ? "error::BytesWarning":
+                                                    "default::BytesWarning";
+    PyObject *option = PyUnicode_FromString(filter);
+    if (option == NULL) {
+        return -1;
+    }
+    if (PyList_Append(warnoptions, option)) {
         Py_DECREF(option);
+        return -1;
     }
+    Py_DECREF(option);
     return 0;
 }
 
 
 static int
-pymain_add_warnings_options(_PyMain *pymain)
+pymain_init_warnoptions(_PyMain *pymain)
 {
-    PySys_ResetWarnOptions();
+    PyObject *warnoptions = PyList_New(0);
+    if (warnoptions == NULL) {
+        return -1;
+    }
 
     /* The priority order for warnings configuration is (highest precedence
      * first):
@@ -846,23 +889,25 @@ pymain_add_warnings_options(_PyMain *pymain)
      * the lowest precedence entries first so that later entries override them.
      */
 
-    if (pymain_add_warning_dev_mode(&pymain->core_config) < 0) {
-        pymain->err = _Py_INIT_NO_MEMORY();
-        return -1;
+    if (pymain_add_warning_dev_mode(warnoptions, &pymain->core_config) < 0) {
+        goto error;
     }
-    if (pymain_add_warnings_optlist(&pymain->env_warning_options) < 0) {
-        pymain->err = _Py_INIT_NO_MEMORY();
-        return -1;
+    if (pymain_add_warnings_optlist(warnoptions, &pymain->env_warning_options) < 0) {
+        goto error;
     }
-    if (pymain_add_warnings_optlist(&pymain->cmdline.warning_options) < 0) {
-        pymain->err = _Py_INIT_NO_MEMORY();
-        return -1;
+    if (pymain_add_warnings_optlist(warnoptions, &pymain->cmdline.warning_options) < 0) {
+        goto error;
     }
-    if (pymain_add_warning_bytes_flag(pymain->cmdline.bytes_warning) < 0) {
-        pymain->err = _Py_INIT_NO_MEMORY();
-        return -1;
+    if (pymain_add_warning_bytes_flag(warnoptions, pymain->cmdline.bytes_warning) < 0) {
+        goto error;
     }
+
+    pymain->config.warnoptions = warnoptions;
     return 0;
+
+error:
+    Py_DECREF(warnoptions);
+    return -1;
 }
 
 
@@ -1092,7 +1137,7 @@ pymain_header(_PyMain *pymain)
 
 
 static int
-pymain_create_argv_list(_PyMain *pymain)
+pymain_init_argv(_PyMain *pymain)
 {
     int argc = pymain->sys_argc;
     wchar_t** argv = pymain->sys_argv;
@@ -1918,7 +1963,6 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, _PyCoreConfig *c
             return err;
         }
     }
-
     return _Py_INIT_OK();
 }
 
@@ -1941,15 +1985,15 @@ pymain_init_python_core(_PyMain *pymain)
 static int
 pymain_init_python_main(_PyMain *pymain)
 {
-    if (pymain_add_xoptions(pymain)) {
+    if (pymain_init_xoptions_dict(pymain)) {
+        pymain->err = _Py_INIT_NO_MEMORY();
         return -1;
     }
-    if (pymain_add_warnings_options(pymain)) {
+    if (pymain_init_warnoptions(pymain)) {
+        pymain->err = _Py_INIT_NO_MEMORY();
         return -1;
     }
-
-    /* Create sys.argv list */
-    if (pymain_create_argv_list(pymain) < 0) {
+    if (pymain_init_argv(pymain) < 0) {
         pymain->err = _Py_INIT_ERR("failed to create sys.argv");
         return -1;
     }
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 31965f503ca..d813ddd6715 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -830,6 +830,8 @@ _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)
 {
     Py_CLEAR(config->argv);
     Py_CLEAR(config->module_search_path);
+    Py_CLEAR(config->warnoptions);
+    Py_CLEAR(config->xoptions);
 }
 
 
@@ -883,10 +885,26 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
         return _Py_INIT_ERR("can't initialize time");
     }
 
+    /* Set sys attributes */
     assert(interp->config.module_search_path != NULL);
     if (PySys_SetObject("path", interp->config.module_search_path) != 0) {
         return _Py_INIT_ERR("can't assign sys.path");
     }
+    if (interp->config.argv != NULL) {
+        if (PySys_SetObject("argv", interp->config.argv) != 0) {
+            return _Py_INIT_ERR("can't assign sys.argv");
+        }
+    }
+    if (interp->config.warnoptions != NULL) {
+        if (PySys_SetObject("warnoptions", interp->config.warnoptions)) {
+            return _Py_INIT_ERR("can't assign sys.warnoptions");
+        }
+    }
+    if (interp->config.xoptions != NULL) {
+        if (PySys_SetObject("_xoptions", interp->config.xoptions)) {
+            return _Py_INIT_ERR("can't assign sys._xoptions");
+        }
+    }
 
     if (_PySys_EndInit(interp->sysdict) < 0)
         return _Py_INIT_ERR("can't finish initializing sys");
@@ -945,13 +963,6 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
             return err;
         }
     }
-
-    if (interp->config.argv != NULL) {
-        if (PySys_SetObject("argv", interp->config.argv) != 0) {
-            return _Py_INIT_ERR("can't assign sys.argv");
-        }
-    }
-
     return _Py_INIT_OK();
 }
 



More information about the Python-checkins mailing list