bpo-34170: Add _PyCoreConfig.bytes_warning (GH-8447)

Add more fields to _PyCoreConfig:

* _check_hash_pycs_mode
* bytes_warning
* debug
* inspect
* interactive
* legacy_windows_fs_encoding
* legacy_windows_stdio
* optimization_level
* quiet
* unbuffered_stdio
* user_site_directory
* verbose
* write_bytecode

Changes:

* Remove pymain_get_global_config() and pymain_set_global_config()
  which became useless. These functions have been replaced by
  _PyCoreConfig_GetGlobalConfig() and
  _PyCoreConfig_SetGlobalConfig().
* sys.flags.dont_write_bytecode value is now restricted to 1 even if
  -B option is specified multiple times on the command line.
* PyThreadState_Clear() now uses the config from the current
  interpreter rather than using global Py_VerboseFlag
diff --git a/Include/pystate.h b/Include/pystate.h
index 609f9c6..84428bc 100644
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -87,18 +87,147 @@
        these manipulations if site is explicitly imported later (call
        site.main() if you want them to be triggered).
 
-       Set to 0 by the -S command line option. If set to -1 (default), set to
-       the negative value of Py_NoSiteFlag. */
+       Set to 0 by the -S command line option. If set to -1 (default), it is
+       set to !Py_NoSiteFlag. */
     int site_import;
 
+    /* Bytes warnings:
+
+       * If equal to 1, issue a warning when comparing bytes or bytearray with
+         str or bytes with int.
+       * If equal or greater to 2, issue an error.
+
+       Incremented by the -b command line option. If set to -1 (default), inherit
+       Py_BytesWarningFlag value. */
+    int bytes_warning;
+
+    /* If greater than 0, enable inspect: when a script is passed as first
+       argument or the -c option is used, enter interactive mode after
+       executing the script or the command, even when sys.stdin does not appear
+       to be a terminal.
+
+       Incremented by the -i command line option. Set to 1 if the PYTHONINSPECT
+       environment variable is non-empty. If set to -1 (default), inherit
+       Py_InspectFlag value. */
+    int inspect;
+
+    /* If greater than 0: enable the interactive mode (REPL).
+
+       Incremented by the -i command line option. If set to -1 (default),
+       inherit Py_InteractiveFlag value. */
+    int interactive;
+
+    /* Optimization level.
+
+       Incremented by the -O command line option. Set by the PYTHONOPTIMIZE
+       environment variable. If set to -1 (default), inherit Py_OptimizeFlag
+       value. */
+    int optimization_level;
+
+    /* If greater than 0, enable the debug mode: turn on parser debugging
+       output (for expert only, depending on compilation options).
+
+       Incremented by the -d command line option. Set by the PYTHONDEBUG
+       environment variable. If set to -1 (default), inherit Py_DebugFlag
+       value. */
+    int debug;
+
+    /* If equal to 0, Python won't try to write ``.pyc`` files on the
+       import of source modules.
+
+       Set to 0 by the -B command line option and the PYTHONDONTWRITEBYTECODE
+       environment variable. If set to -1 (default), it is set to
+       !Py_DontWriteBytecodeFlag. */
+    int write_bytecode;
+
+    /* If greater than 0, enable the verbose mode: print a message each time a
+       module is initialized, showing the place (filename or built-in module)
+       from which it is loaded.
+
+       If greater or equal to 2, print a message for each file that is checked
+       for when searching for a module. Also provides information on module
+       cleanup at exit.
+
+       Incremented by the -v option. Set by the PYTHONVERBOSE environment
+       variable. If set to -1 (default), inherit Py_VerboseFlag value. */
+    int verbose;
+
+    /* If greater than 0, enable the quiet mode: Don't display the copyright
+       and version messages even in interactive mode.
+
+       Incremented by the -q option. If set to -1 (default), inherit
+       Py_QuietFlag value. */
+    int quiet;
+
+   /* If greater than 0, don't add the user site-packages directory to
+      sys.path.
+
+      Set to 0 by the -s and -I command line options , and the PYTHONNOUSERSITE
+      environment variable. If set to -1 (default), it is set to
+      !Py_NoUserSiteDirectory. */
+    int user_site_directory;
+
+    /* If greater than 0, enable unbuffered mode: force the stdout and stderr
+       streams to be unbuffered.
+
+       Set to 1 by the -u option. Set by the PYTHONUNBUFFERED environment
+       variable. If set to -1 (default), inherit Py_UnbufferedStdioFlag
+       value. */
+    int unbuffered_stdio;
+
+#ifdef MS_WINDOWS
+    /* If greater than 1, use the "mbcs" encoding instead of the UTF-8
+       encoding for the filesystem encoding.
+
+       Set to 1 if the PYTHONLEGACYWINDOWSFSENCODING environment variable is
+       set to a non-empty string. If set to -1 (default), inherit
+       Py_LegacyWindowsFSEncodingFlag value.
+
+       See PEP 529 for more details. */
+    int legacy_windows_fs_encoding;
+
+    /* If greater than zero, use io.FileIO instead of WindowsConsoleIO for sys
+       standard streams.
+
+       Set to 1 if the PYTHONLEGACYWINDOWSSTDIO environment variable is set to
+       a non-empty string. If set to -1 (default), inherit
+       Py_LegacyWindowsStdioFlag value.
+
+       See PEP 528 for more details. */
+    int legacy_windows_stdio;
+#endif
+
     /* --- Private fields -------- */
 
     /* Install importlib? If set to 0, importlib is not initialized at all.
        Needed by freeze_importlib: see install_importlib argument of
        _Py_InitializeEx_Private(). */
     int _install_importlib;
+
+    /* Value of the --check-hash-based-pycs configure option. Valid values:
+
+       - "default" means the 'check_source' flag in hash-based pycs
+         determines invalidation
+       - "always" causes the interpreter to hash the source file for
+         invalidation regardless of value of 'check_source' bit
+       - "never" causes the interpreter to always assume hash-based pycs are
+         valid
+
+       Set by the --check-hash-based-pycs command line option.
+       If set to NULL (default), inherit _Py_CheckHashBasedPycsMode value.
+
+       See PEP 552 "Deterministic pycs" for more details. */
+    const char *_check_hash_pycs_mode;
 } _PyCoreConfig;
 
+#ifdef MS_WINDOWS
+#  define _PyCoreConfig_WINDOWS_INIT \
+        .legacy_windows_fs_encoding = -1, \
+        .legacy_windows_stdio = -1,
+#else
+#  define _PyCoreConfig_WINDOWS_INIT
+#endif
+
 #define _PyCoreConfig_INIT \
     (_PyCoreConfig){ \
         .install_signal_handlers = -1, \
@@ -110,6 +239,17 @@
         .nmodule_search_path = -1, \
         .isolated = -1, \
         .site_import = -1, \
+        .bytes_warning = -1, \
+        .inspect = -1, \
+        .interactive = -1, \
+        .optimization_level = -1, \
+        .debug= -1, \
+        .write_bytecode = -1, \
+        .verbose = -1, \
+        .quiet = -1, \
+        .user_site_directory = -1, \
+        .unbuffered_stdio = -1, \
+        _PyCoreConfig_WINDOWS_INIT \
         ._install_importlib = 1}
 /* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */
 
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index ce14a96..0346074 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -507,13 +507,15 @@
                 PYTHONDONTWRITEBYTECODE=value,
                 PYTHONVERBOSE=value,
             )
+            dont_write_bytecode = int(bool(value))
             code = (
                 "import sys; "
                 "sys.stderr.write(str(sys.flags)); "
                 f"""sys.exit(not (
                     sys.flags.debug == sys.flags.optimize ==
-                    sys.flags.dont_write_bytecode == sys.flags.verbose ==
+                    sys.flags.verbose ==
                     {expected}
+                    and sys.flags.dont_write_bytecode == {dont_write_bytecode}
                 ))"""
             )
             with self.subTest(envar_value=value):
diff --git a/Modules/main.c b/Modules/main.c
index c9fd300..73ffecd 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -415,29 +415,12 @@
 
 typedef struct {
     wchar_t **argv;
-    int nwarnoption;             /* Number of -W options */
-    wchar_t **warnoptions;       /* -W options */
-    int nenv_warnoption;         /* Number of PYTHONWARNINGS options */
-    wchar_t **env_warnoptions;   /* PYTHONWARNINGS options */
+    int nwarnoption;             /* Number of -W command line options */
+    wchar_t **warnoptions;       /* Command line -W options */
+    int nenv_warnoption;         /* Number of PYTHONWARNINGS environment variables */
+    wchar_t **env_warnoptions;   /* PYTHONWARNINGS environment variables */
     int print_help;              /* -h, -? options */
     int print_version;           /* -V option */
-    int bytes_warning;           /* Py_BytesWarningFlag, -b */
-    int debug;                   /* Py_DebugFlag, -b, PYTHONDEBUG */
-    int inspect;                 /* Py_InspectFlag, -i, PYTHONINSPECT */
-    int interactive;             /* Py_InteractiveFlag, -i */
-    int optimization_level;      /* Py_OptimizeFlag, -O, PYTHONOPTIMIZE */
-    int dont_write_bytecode;     /* Py_DontWriteBytecodeFlag, -B, PYTHONDONTWRITEBYTECODE */
-    int no_user_site_directory;  /* Py_NoUserSiteDirectory, -I, -s, PYTHONNOUSERSITE */
-    int use_unbuffered_io;       /* Py_UnbufferedStdioFlag, -u, PYTHONUNBUFFERED */
-    int verbosity;               /* Py_VerboseFlag, -v, PYTHONVERBOSE */
-    int quiet_flag;              /* Py_QuietFlag, -q */
-    const char *check_hash_pycs_mode; /* --check-hash-based-pycs */
-#ifdef MS_WINDOWS
-    int legacy_windows_fs_encoding;  /* Py_LegacyWindowsFSEncodingFlag,
-                                        PYTHONLEGACYWINDOWSFSENCODING */
-    int legacy_windows_stdio;        /* Py_LegacyWindowsStdioFlag,
-                                        PYTHONLEGACYWINDOWSSTDIO */
-#endif
 } _Py_CommandLineDetails;
 
 /* Structure used by Py_Main() to pass data to subfunctions */
@@ -570,42 +553,41 @@
 static void
 _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
 {
-    if (config->ignore_environment == -1) {
-        config->ignore_environment = Py_IgnoreEnvironmentFlag;
-    }
-    if (config->utf8_mode == -1) {
-        config->utf8_mode = Py_UTF8Mode;
-    }
-    if (config->isolated == -1) {
-        config->isolated = Py_IsolatedFlag;
-    }
-    if (config->site_import == -1) {
-        config->site_import = !Py_NoSiteFlag;
-    }
-}
+#define COPY_FLAG(ATTR, VALUE) \
+        if (config->ATTR == -1) { \
+            config->ATTR = VALUE; \
+        }
+#define COPY_NOT_FLAG(ATTR, VALUE) \
+        if (config->ATTR == -1) { \
+            config->ATTR = !(VALUE); \
+        }
 
-
-/* Get Py_xxx global configuration variables */
-static void
-pymain_get_global_config(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
-{
-    _PyCoreConfig_GetGlobalConfig(&pymain->config);
-
-    cmdline->bytes_warning = Py_BytesWarningFlag;
-    cmdline->debug = Py_DebugFlag;
-    cmdline->inspect = Py_InspectFlag;
-    cmdline->interactive = Py_InteractiveFlag;
-    cmdline->optimization_level = Py_OptimizeFlag;
-    cmdline->dont_write_bytecode = Py_DontWriteBytecodeFlag;
-    cmdline->no_user_site_directory = Py_NoUserSiteDirectory;
-    cmdline->use_unbuffered_io = Py_UnbufferedStdioFlag;
-    cmdline->verbosity = Py_VerboseFlag;
-    cmdline->quiet_flag = Py_QuietFlag;
+    COPY_FLAG(ignore_environment, Py_IgnoreEnvironmentFlag);
+    COPY_FLAG(utf8_mode, Py_UTF8Mode);
+    COPY_FLAG(isolated, Py_IsolatedFlag);
+    COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
+    COPY_FLAG(inspect, Py_InspectFlag);
+    COPY_FLAG(interactive, Py_InteractiveFlag);
+    COPY_FLAG(optimization_level, Py_OptimizeFlag);
+    COPY_FLAG(debug, Py_DebugFlag);
+    COPY_FLAG(verbose, Py_VerboseFlag);
+    COPY_FLAG(quiet, Py_QuietFlag);
+    COPY_FLAG(unbuffered_stdio, Py_UnbufferedStdioFlag);
 #ifdef MS_WINDOWS
-    cmdline->legacy_windows_fs_encoding = Py_LegacyWindowsFSEncodingFlag;
-    cmdline->legacy_windows_stdio = Py_LegacyWindowsStdioFlag;
+    COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
+    COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
 #endif
-    cmdline->check_hash_pycs_mode = _Py_CheckHashBasedPycsMode ;
+
+    COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
+    COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
+    COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
+
+    if (config->_check_hash_pycs_mode == NULL) {
+        config->_check_hash_pycs_mode = _Py_CheckHashBasedPycsMode;
+    }
+
+#undef COPY_FLAG
+#undef COPY_NOT_FLAG
 }
 
 
@@ -613,46 +595,45 @@
 void
 _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
 {
-    if (config->ignore_environment != -1) {
-        Py_IgnoreEnvironmentFlag = config->ignore_environment;
-    }
-    if (config->utf8_mode != -1) {
-        Py_UTF8Mode = config->utf8_mode;
-    }
-    if (config->isolated != -1) {
-        Py_IsolatedFlag = config->isolated;
-    }
-    if (config->site_import != -1) {
-        Py_NoSiteFlag = !config->site_import;
+#define COPY_FLAG(ATTR, VAR) \
+        if (config->ATTR != -1) { \
+            VAR = config->ATTR; \
+        }
+#define COPY_NOT_FLAG(ATTR, VAR) \
+        if (config->ATTR != -1) { \
+            VAR = !config->ATTR; \
+        }
+
+    COPY_FLAG(ignore_environment, Py_IgnoreEnvironmentFlag);
+    COPY_FLAG(utf8_mode, Py_UTF8Mode);
+    COPY_FLAG(isolated, Py_IsolatedFlag);
+    COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
+    COPY_FLAG(inspect, Py_InspectFlag);
+    COPY_FLAG(interactive, Py_InteractiveFlag);
+    COPY_FLAG(optimization_level, Py_OptimizeFlag);
+    COPY_FLAG(debug, Py_DebugFlag);
+    COPY_FLAG(verbose, Py_VerboseFlag);
+    COPY_FLAG(quiet, Py_QuietFlag);
+    COPY_FLAG(unbuffered_stdio, Py_UnbufferedStdioFlag);
+#ifdef MS_WINDOWS
+    COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
+    COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
+#endif
+
+    COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
+    COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag);
+    COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory);
+
+    if (config->_check_hash_pycs_mode != NULL) {
+        _Py_CheckHashBasedPycsMode = config->_check_hash_pycs_mode;
     }
 
     /* Random or non-zero hash seed */
     Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
                                 config->hash_seed != 0);
-}
 
-
-/* Set Py_xxx global configuration variables */
-static void
-pymain_set_global_config(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
-{
-    _PyCoreConfig_SetGlobalConfig(&pymain->config);
-
-    Py_BytesWarningFlag = cmdline->bytes_warning;
-    Py_DebugFlag = cmdline->debug;
-    Py_InspectFlag = cmdline->inspect;
-    Py_InteractiveFlag = cmdline->interactive;
-    Py_OptimizeFlag = cmdline->optimization_level;
-    Py_DontWriteBytecodeFlag = cmdline->dont_write_bytecode;
-    Py_NoUserSiteDirectory = cmdline->no_user_site_directory;
-    Py_UnbufferedStdioFlag = cmdline->use_unbuffered_io;
-    Py_VerboseFlag = cmdline->verbosity;
-    Py_QuietFlag = cmdline->quiet_flag;
-    _Py_CheckHashBasedPycsMode = cmdline->check_hash_pycs_mode;
-#ifdef MS_WINDOWS
-    Py_LegacyWindowsFSEncodingFlag = cmdline->legacy_windows_fs_encoding;
-    Py_LegacyWindowsStdioFlag = cmdline->legacy_windows_stdio;
-#endif
+#undef COPY_FLAG
+#undef COPY_NOT_FLAG
 }
 
 
@@ -762,6 +743,21 @@
 
     COPY_ATTR(isolated);
     COPY_ATTR(site_import);
+    COPY_ATTR(bytes_warning);
+    COPY_ATTR(inspect);
+    COPY_ATTR(interactive);
+    COPY_ATTR(optimization_level);
+    COPY_ATTR(debug);
+    COPY_ATTR(write_bytecode);
+    COPY_ATTR(verbose);
+    COPY_ATTR(quiet);
+    COPY_ATTR(user_site_directory);
+    COPY_ATTR(unbuffered_stdio);
+#ifdef MS_WINDOWS
+    COPY_ATTR(legacy_windows_fs_encoding);
+    COPY_ATTR(legacy_windows_stdio);
+#endif
+    COPY_ATTR(_check_hash_pycs_mode);
 
 #undef COPY_ATTR
 #undef COPY_STR_ATTR
@@ -990,11 +986,11 @@
             // Handle long option.
             assert(longindex == 0); // Only one long option now.
             if (!wcscmp(_PyOS_optarg, L"always")) {
-                cmdline->check_hash_pycs_mode = "always";
+                config->_check_hash_pycs_mode = "always";
             } else if (!wcscmp(_PyOS_optarg, L"never")) {
-                cmdline->check_hash_pycs_mode = "never";
+                config->_check_hash_pycs_mode = "never";
             } else if (!wcscmp(_PyOS_optarg, L"default")) {
-                cmdline->check_hash_pycs_mode = "default";
+                config->_check_hash_pycs_mode = "default";
             } else {
                 fprintf(stderr, "--check-hash-based-pycs must be one of "
                         "'default', 'always', or 'never'\n");
@@ -1003,36 +999,36 @@
             break;
 
         case 'b':
-            cmdline->bytes_warning++;
+            config->bytes_warning++;
             break;
 
         case 'd':
-            cmdline->debug++;
+            config->debug++;
             break;
 
         case 'i':
-            cmdline->inspect++;
-            cmdline->interactive++;
+            config->inspect++;
+            config->interactive++;
             break;
 
         case 'I':
             config->ignore_environment++;
             config->isolated++;
-            cmdline->no_user_site_directory++;
+            config->user_site_directory = 0;
             break;
 
         /* case 'J': reserved for Jython */
 
         case 'O':
-            cmdline->optimization_level++;
+            config->optimization_level++;
             break;
 
         case 'B':
-            cmdline->dont_write_bytecode++;
+            config->write_bytecode = 0;
             break;
 
         case 's':
-            cmdline->no_user_site_directory++;
+            config->user_site_directory = 0;
             break;
 
         case 'S':
@@ -1048,11 +1044,11 @@
             break;
 
         case 'u':
-            cmdline->use_unbuffered_io = 1;
+            config->unbuffered_stdio = 1;
             break;
 
         case 'v':
-            cmdline->verbosity++;
+            config->verbose++;
             break;
 
         case 'x':
@@ -1087,7 +1083,7 @@
             break;
 
         case 'q':
-            cmdline->quiet_flag++;
+            config->quiet++;
             break;
 
         case 'R':
@@ -1237,9 +1233,9 @@
      * don't even try to emit a warning, so we skip setting the filter in that
      * case.
      */
-    if (cmdline->bytes_warning) {
+    if (config->bytes_warning) {
         wchar_t *filter;
-        if (cmdline->bytes_warning> 1) {
+        if (config->bytes_warning> 1) {
             filter = L"error::BytesWarning";
         }
         else {
@@ -1299,8 +1295,10 @@
 static void
 pymain_init_stdio(_PyMain *pymain)
 {
+    _PyCoreConfig *config = &pymain->config;
+
     pymain->stdin_is_interactive = (isatty(fileno(stdin))
-                                    || Py_InteractiveFlag);
+                                    || config->interactive);
 
 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
     /* don't translate newlines (\r\n <=> \n) */
@@ -1309,7 +1307,7 @@
     _setmode(fileno(stderr), O_BINARY);
 #endif
 
-    if (Py_UnbufferedStdioFlag) {
+    if (config->unbuffered_stdio) {
 #ifdef HAVE_SETVBUF
         setvbuf(stdin,  (char *)NULL, _IONBF, BUFSIZ);
         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
@@ -1320,7 +1318,7 @@
         setbuf(stderr, (char *)NULL);
 #endif /* !HAVE_SETVBUF */
     }
-    else if (Py_InteractiveFlag) {
+    else if (config->interactive) {
 #ifdef MS_WINDOWS
         /* Doesn't have to have line-buffered -- use unbuffered */
         /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
@@ -1886,17 +1884,29 @@
 cmdline_get_env_flags(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 {
     _PyCoreConfig *config = &pymain->config;
-    get_env_flag(config, &cmdline->debug, "PYTHONDEBUG");
-    get_env_flag(config, &cmdline->verbosity, "PYTHONVERBOSE");
-    get_env_flag(config, &cmdline->optimization_level, "PYTHONOPTIMIZE");
-    get_env_flag(config, &cmdline->inspect, "PYTHONINSPECT");
-    get_env_flag(config, &cmdline->dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
-    get_env_flag(config, &cmdline->no_user_site_directory, "PYTHONNOUSERSITE");
-    get_env_flag(config, &cmdline->use_unbuffered_io, "PYTHONUNBUFFERED");
+
+    get_env_flag(config, &config->debug, "PYTHONDEBUG");
+    get_env_flag(config, &config->verbose, "PYTHONVERBOSE");
+    get_env_flag(config, &config->optimization_level, "PYTHONOPTIMIZE");
+    get_env_flag(config, &config->inspect, "PYTHONINSPECT");
+
+    int dont_write_bytecode = 0;
+    get_env_flag(config, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
+    if (dont_write_bytecode) {
+        config->write_bytecode = 0;
+    }
+
+    int no_user_site_directory = 0;
+    get_env_flag(config, &no_user_site_directory, "PYTHONNOUSERSITE");
+    if (no_user_site_directory) {
+        config->user_site_directory = 0;
+    }
+
+    get_env_flag(config, &config->unbuffered_stdio, "PYTHONUNBUFFERED");
 #ifdef MS_WINDOWS
-    get_env_flag(config, &cmdline->legacy_windows_fs_encoding,
+    get_env_flag(config, &config->legacy_windows_fs_encoding,
                  "PYTHONLEGACYWINDOWSFSENCODING");
-    get_env_flag(config, &cmdline->legacy_windows_stdio,
+    get_env_flag(config, &config->legacy_windows_stdio,
                  "PYTHONLEGACYWINDOWSSTDIO");
 #endif
 }
@@ -2077,6 +2087,7 @@
 static int
 pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 {
+    _PyCoreConfig *config = &pymain->config;
     _PyInitError err;
 
     int res = pymain_parse_cmdline(pymain, cmdline);
@@ -2094,8 +2105,8 @@
     }
 
 #ifdef MS_WINDOWS
-    if (cmdline->legacy_windows_fs_encoding) {
-        pymain->config.utf8_mode = 0;
+    if (config->legacy_windows_fs_encoding) {
+        config->utf8_mode = 0;
     }
 #endif
 
@@ -2103,7 +2114,7 @@
         return -1;
     }
 
-    err = _PyCoreConfig_Read(&pymain->config);
+    err = _PyCoreConfig_Read(config);
 
     if (_Py_INIT_FAILED(err)) {
         pymain->err = err;
@@ -2203,7 +2214,6 @@
         }
         pymain_clear_cmdline(pymain, cmdline);
         memset(cmdline, 0, sizeof(*cmdline));
-        pymain_get_global_config(pymain, cmdline);
         pymain->config.utf8_mode = new_utf8_mode;
 
         /* The encoding changed: read again the configuration
@@ -2615,12 +2625,8 @@
     _Py_CommandLineDetails cmdline;
     memset(&cmdline, 0, sizeof(cmdline));
 
-    pymain_get_global_config(pymain, &cmdline);
-
     int res = pymain_cmdline_impl(pymain, &cmdline);
 
-    pymain_set_global_config(pymain, &cmdline);
-
     pymain_clear_cmdline(pymain, &cmdline);
 
 #ifdef Py_DEBUG
@@ -2639,6 +2645,8 @@
 {
     pymain_init(pymain);
 
+    _PyCoreConfig_GetGlobalConfig(&pymain->config);
+
     int res = pymain_cmdline(pymain);
     if (res < 0) {
         _Py_FatalInitError(pymain->err);
@@ -2647,6 +2655,8 @@
         goto done;
     }
 
+    _PyCoreConfig_SetGlobalConfig(&pymain->config);
+
     pymain_init_stdio(pymain);
 
     /* bpo-34008: For backward compatibility reasons, calling Py_Main() after
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 9d32965..4e2bb60 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -999,12 +999,13 @@
 static PyObject *
 bytearray_str(PyObject *op)
 {
-        if (Py_BytesWarningFlag) {
-                if (PyErr_WarnEx(PyExc_BytesWarning,
-                                 "str() on a bytearray instance", 1))
-                        return NULL;
+    if (Py_BytesWarningFlag) {
+        if (PyErr_WarnEx(PyExc_BytesWarning,
+                         "str() on a bytearray instance", 1)) {
+                return NULL;
         }
-        return bytearray_repr((PyByteArrayObject*)op);
+    }
+    return bytearray_repr((PyByteArrayObject*)op);
 }
 
 static PyObject *
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 943c329..648b2a5 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -1416,8 +1416,9 @@
 {
     if (Py_BytesWarningFlag) {
         if (PyErr_WarnEx(PyExc_BytesWarning,
-                         "str() on a bytes instance", 1))
+                         "str() on a bytes instance", 1)) {
             return NULL;
+        }
     }
     return bytes_repr(op);
 }
diff --git a/Parser/pgenmain.c b/Parser/pgenmain.c
index 20ef8a7..0a4b0c5 100644
--- a/Parser/pgenmain.c
+++ b/Parser/pgenmain.c
@@ -24,9 +24,9 @@
 #include "parsetok.h"
 #include "pgen.h"
 
-int Py_DebugFlag;
-int Py_VerboseFlag;
-int Py_IgnoreEnvironmentFlag;
+int Py_DebugFlag = 0;
+int Py_VerboseFlag = 0;
+int Py_IgnoreEnvironmentFlag = 0;
 _PyRuntimeState _PyRuntime = _PyRuntimeState_INIT;
 
 /* Forward */
diff --git a/Python/pystate.c b/Python/pystate.c
index 629598e..e8d390d 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -568,7 +568,9 @@
 void
 PyThreadState_Clear(PyThreadState *tstate)
 {
-    if (Py_VerboseFlag && tstate->frame != NULL)
+    int verbose = tstate->interp->core_config.verbose;
+
+    if (verbose && tstate->frame != NULL)
         fprintf(stderr,
           "PyThreadState_Clear: warning: thread still has a frame\n");
 
@@ -586,7 +588,7 @@
     Py_CLEAR(tstate->exc_state.exc_traceback);
 
     /* The stack of exception states should contain just this thread. */
-    if (Py_VerboseFlag && tstate->exc_info != &tstate->exc_state) {
+    if (verbose && tstate->exc_info != &tstate->exc_state) {
         fprintf(stderr,
           "PyThreadState_Clear: warning: thread still has a generator\n");
     }