]> granicus.if.org Git - python/commitdiff
bpo-36763: Add _PyCoreConfig.configure_c_stdio (GH-13363)
authorVictor Stinner <vstinner@redhat.com>
Thu, 16 May 2019 16:30:15 +0000 (18:30 +0200)
committerGitHub <noreply@github.com>
Thu, 16 May 2019 16:30:15 +0000 (18:30 +0200)
Add tests for configure_c_stdio and pathconfig_warnings parameters.

Include/cpython/coreconfig.h
Lib/test/test_embed.py
Programs/_testembed.c
Python/coreconfig.c

index c2c556684068b770db6980a0a1e271914d2a9758..b531118ea3cf149ebba8249ffc922d6ca15be3a6 100644 (file)
@@ -312,6 +312,14 @@ typedef struct {
       !Py_NoUserSiteDirectory. */
     int user_site_directory;
 
+    /* If non-zero, configure C standard steams (stdio, stdout,
+       stderr):
+
+       - Set O_BINARY mode on Windows.
+       - If buffered_stdio is equal to zero, make streams unbuffered.
+         Otherwise, enable streams buffering if interactive is non-zero. */
+    int configure_c_stdio;
+
     /* If equal to 0, enable unbuffered mode: force the stdout and stderr
        streams to be unbuffered.
 
@@ -439,6 +447,7 @@ typedef struct {
         .verbose = -1, \
         .quiet = -1, \
         .user_site_directory = -1, \
+        .configure_c_stdio = 1, \
         .buffered_stdio = -1, \
         ._install_importlib = 1, \
         .check_hash_pycs_mode = NULL, \
index c3c1a3e3bacd109ad3435193f6dbbc36127ff238..b1872ace8a60cb6b2d589789087ec53289b1b556 100644 (file)
@@ -331,6 +331,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         'verbose': 0,
         'quiet': 0,
         'user_site_directory': 1,
+        'configure_c_stdio': 1,
         'buffered_stdio': 1,
 
         'stdio_encoding': GET_DEFAULT_CONFIG,
@@ -558,6 +559,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
             'filesystem_encoding': 'utf-8',
             'filesystem_errors': self.UTF8_MODE_ERRORS,
             'user_site_directory': 0,
+            'pathconfig_warnings': 0,
         }
         self.check_config("init_global_config", config, preconfig)
 
@@ -597,11 +599,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
             'write_bytecode': 0,
             'verbose': 1,
             'quiet': 1,
+            'configure_c_stdio': 0,
             'buffered_stdio': 0,
             'user_site_directory': 0,
             'faulthandler': 1,
 
             'check_hash_pycs_mode': 'always',
+            'pathconfig_warnings': 0,
         }
         self.check_config("init_from_config", config, preconfig)
 
index 4ee2cd1b40707e3367275972bb1f44e61512656e..87d159fe7219ac146b63268ebd56f7bc4a2884cf 100644 (file)
@@ -360,6 +360,8 @@ static int test_init_global_config(void)
     putenv("PYTHONUNBUFFERED=");
     Py_UnbufferedStdioFlag = 1;
 
+    Py_FrozenFlag = 1;
+
     /* FIXME: test Py_LegacyWindowsFSEncodingFlag */
     /* FIXME: test Py_LegacyWindowsStdioFlag */
 
@@ -481,6 +483,8 @@ static int test_init_from_config(void)
     Py_QuietFlag = 0;
     config.quiet = 1;
 
+    config.configure_c_stdio = 0;
+
     putenv("PYTHONUNBUFFERED=");
     Py_UnbufferedStdioFlag = 0;
     config.buffered_stdio = 0;
@@ -501,6 +505,9 @@ static int test_init_from_config(void)
 
     config.check_hash_pycs_mode = L"always";
 
+    Py_FrozenFlag = 0;
+    config.pathconfig_warnings = 0;
+
     err = _Py_InitializeFromConfig(&config);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
index 8a5e5d509cbcceae802f6c6b16d72a225393a1b4..e51bf9424a308390b86361471672b1955e034334 100644 (file)
@@ -654,6 +654,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
     COPY_ATTR(verbose);
     COPY_ATTR(quiet);
     COPY_ATTR(user_site_directory);
+    COPY_ATTR(configure_c_stdio);
     COPY_ATTR(buffered_stdio);
     COPY_WSTR_ATTR(filesystem_encoding);
     COPY_WSTR_ATTR(filesystem_errors);
@@ -755,6 +756,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
     SET_ITEM_INT(verbose);
     SET_ITEM_INT(quiet);
     SET_ITEM_INT(user_site_directory);
+    SET_ITEM_INT(configure_c_stdio);
     SET_ITEM_INT(buffered_stdio);
     SET_ITEM_WSTR(stdio_encoding);
     SET_ITEM_WSTR(stdio_errors);
@@ -1582,7 +1584,6 @@ config_read(_PyCoreConfig *config, _PyPreCmdline *cmdline)
             return _Py_INIT_NO_MEMORY();
         }
     }
-
     return _Py_INIT_OK();
 }
 
@@ -1632,7 +1633,10 @@ void
 _PyCoreConfig_Write(const _PyCoreConfig *config, _PyRuntimeState *runtime)
 {
     _PyCoreConfig_SetGlobalConfig(config);
-    config_init_stdio(config);
+
+    if (config->configure_c_stdio) {
+        config_init_stdio(config);
+    }
 
     /* Write the new pre-configuration into _PyRuntime */
     _PyPreConfig *preconfig = &runtime->preconfig;
@@ -2067,6 +2071,9 @@ config_read_cmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline)
     if (config->parse_argv < 0) {
         config->parse_argv = 1;
     }
+    if (config->configure_c_stdio < 0) {
+        config->configure_c_stdio = 1;
+    }
 
     if (config->parse_argv) {
         int opt_index;
@@ -2171,7 +2178,9 @@ _PyCoreConfig_SetWideArgv(_PyCoreConfig *config, int argc, wchar_t **argv)
 
    * Command line arguments
    * Environment variables
-   * Py_xxx global configuration variables */
+   * Py_xxx global configuration variables
+
+   The only side effects are to modify config and to call _Py_SetArgcArgv(). */
 _PyInitError
 _PyCoreConfig_Read(_PyCoreConfig *config)
 {
@@ -2227,14 +2236,19 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
     assert(config->quiet >= 0);
     assert(config->user_site_directory >= 0);
     assert(config->parse_argv >= 0);
+    assert(config->configure_c_stdio >= 0);
     assert(config->buffered_stdio >= 0);
     assert(config->program_name != NULL);
     assert(config->program != NULL);
     assert(_PyWstrList_CheckConsistency(&config->argv));
+    /* sys.argv must be non-empty: empty argv is replaced with [''] */
+    assert(config->argv.length >= 1);
     assert(_PyWstrList_CheckConsistency(&config->xoptions));
     assert(_PyWstrList_CheckConsistency(&config->warnoptions));
     assert(_PyWstrList_CheckConsistency(&config->module_search_paths));
     if (config->_install_importlib) {
+        assert(config->use_module_search_paths != 0);
+        /* don't check config->module_search_paths */
         assert(config->executable != NULL);
         assert(config->prefix != NULL);
         assert(config->base_prefix != NULL);