https://github.com/python/cpython/commit/7242fea93c1fc1366350a377ad2e50ff071acd4b
commit: 7242fea93c1fc1366350a377ad2e50ff071acd4b
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-09-24T16:42:02+02:00
summary:

gh-158001: Remove global configuration variables from C API (#158020)

Keep 4 variables in the stable ABI:

* Py_FileSystemDefaultEncodeErrors
* Py_FileSystemDefaultEncoding
* Py_HasFileSystemDefaultEncoding
* Py_UTF8Mode

Mark the 4 variables as ABI only in Misc/stable_abi.toml.

files:
A Misc/NEWS.d/next/C_API/2026-09-23-19-37-53.gh-issue-158001.X_Xamm.rst
M Doc/c-api/interp-lifecycle.rst
M Doc/data/stable_abi.dat
M Doc/deprecations/c-api-pending-removal-in-3.16.rst
M Doc/tools/removed-ids.txt
M Doc/whatsnew/3.12.rst
M Doc/whatsnew/3.16.rst
M Doc/whatsnew/3.7.rst
M Include/cpython/pydebug.h
M Include/fileobject.h
M Include/internal/pycore_fileutils.h
M Lib/test/test_capi/test_config.py
M Lib/test/test_ctypes/test_values.py
M Lib/test/test_embed.py
M Misc/NEWS.d/next/C_API/2026-07-08-00-38-32.gh-issue-153300.lVoWyR.rst
M Misc/stable_abi.toml
M Programs/_testembed.c
M Python/initconfig.c
M Python/preconfig.c
M Tools/c-analyzer/cpython/ignored.tsv

diff --git a/Doc/c-api/interp-lifecycle.rst b/Doc/c-api/interp-lifecycle.rst
index 6f832b7a34b10b9..bd4125cacdd0e66 100644
--- a/Doc/c-api/interp-lifecycle.rst
+++ b/Doc/c-api/interp-lifecycle.rst
@@ -15,8 +15,7 @@ Before Python initialization
 
 In an application embedding Python, the :c:func:`Py_Initialize` function must
 be called before using any other Python/C API functions; with the exception of
-a few functions and the :ref:`global configuration variables
-<global-conf-vars>`.
+a few functions.
 
 The following functions can be safely called before Python is initialized:
 
@@ -75,277 +74,6 @@ The following functions can be safely called before Python 
is initialized:
    been initialized: :c:func:`Py_EncodeLocale`, and :c:func:`Py_RunMain`.
 
 
-.. _global-conf-vars:
-
-Global configuration variables
-------------------------------
-
-Python has variables for the global configuration to control different features
-and options. By default, these flags are controlled by :ref:`command line
-options <using-on-interface-options>`.
-
-When a flag is set by an option, the value of the flag is the number of times
-that the option was set. For example, ``-b`` sets :c:data:`Py_BytesWarningFlag`
-to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2.
-
-
-.. c:var:: int Py_BytesWarningFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.bytes_warning` should be used instead, see :ref:`Python
-   Initialization Configuration <init-config>`.
-
-   Issue a warning when comparing :class:`bytes` or :class:`bytearray` with
-   :class:`str` or :class:`bytes` with :class:`int`.  Issue an error if greater
-   or equal to ``2``.
-
-   Set by the :option:`-b` option.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_DebugFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.parser_debug` should be used instead, see :ref:`Python
-   Initialization Configuration <init-config>`.
-
-   Turn on parser debugging output (for expert only, depending on compilation
-   options).
-
-   Set by the :option:`-d` option and the :envvar:`PYTHONDEBUG` environment
-   variable.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_DontWriteBytecodeFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.write_bytecode` should be used instead, see :ref:`Python
-   Initialization Configuration <init-config>`.
-
-   If set to non-zero, Python won't try to write ``.pyc`` files on the
-   import of source modules.
-
-   Set by the :option:`-B` option and the :envvar:`PYTHONDONTWRITEBYTECODE`
-   environment variable.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_FrozenFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.pathconfig_warnings` should be used instead, see
-   :ref:`Python Initialization Configuration <init-config>`.
-
-   Private flag used by ``_freeze_module`` and ``frozenmain`` programs.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_HashRandomizationFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.hash_seed` and :c:member:`PyConfig.use_hash_seed` should
-   be used instead, see :ref:`Python Initialization Configuration
-   <init-config>`.
-
-   Set to ``1`` if the :envvar:`PYTHONHASHSEED` environment variable is set to
-   a non-empty string.
-
-   If the flag is non-zero, read the :envvar:`PYTHONHASHSEED` environment
-   variable to initialize the secret hash seed.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_IgnoreEnvironmentFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.use_environment` should be used instead, see
-   :ref:`Python Initialization Configuration <init-config>`.
-
-   Ignore all :envvar:`!PYTHON*` environment variables, e.g.
-   :envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set.
-
-   Set by the :option:`-E` and :option:`-I` options.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_InspectFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.inspect` should be used instead, see
-   :ref:`Python Initialization Configuration <init-config>`.
-
-   When a script is passed as first argument or the :option:`-c` option is 
used,
-   enter interactive mode after executing the script or the command, even when
-   :data:`sys.stdin` does not appear to be a terminal.
-
-   Set by the :option:`-i` option and the :envvar:`PYTHONINSPECT` environment
-   variable.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_InteractiveFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.interactive` should be used instead, see
-   :ref:`Python Initialization Configuration <init-config>`.
-
-   Set by the :option:`-i` option.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_IsolatedFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.isolated` should be used instead, see
-   :ref:`Python Initialization Configuration <init-config>`.
-
-   Run Python in isolated mode. In isolated mode :data:`sys.path` contains
-   neither the script's directory nor the user's site-packages directory.
-
-   Set by the :option:`-I` option.
-
-   .. versionadded:: 3.4
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_LegacyWindowsFSEncodingFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyPreConfig.legacy_windows_fs_encoding` should be used instead, 
see
-   :ref:`Python Initialization Configuration <init-config>`.
-
-   If the flag is non-zero, use the ``mbcs`` encoding with ``replace`` error
-   handler, instead of the UTF-8 encoding with ``surrogatepass`` error handler,
-   for the :term:`filesystem encoding and error handler`.
-
-   Set to ``1`` if the :envvar:`PYTHONLEGACYWINDOWSFSENCODING` environment
-   variable is set to a non-empty string.
-
-   See :pep:`529` for more details.
-
-   .. availability:: Windows.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_LegacyWindowsStdioFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.legacy_windows_stdio` should be used instead, see
-   :ref:`Python Initialization Configuration <init-config>`.
-
-   If the flag is non-zero, use :class:`io.FileIO` instead of
-   :class:`!io._WindowsConsoleIO` for :mod:`sys` standard streams.
-
-   Set to ``1`` if the :envvar:`PYTHONLEGACYWINDOWSSTDIO` environment
-   variable is set to a non-empty string.
-
-   See :pep:`528` for more details.
-
-   .. availability:: Windows.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_NoSiteFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.site_import` should be used instead, see
-   :ref:`Python Initialization Configuration <init-config>`.
-
-   Disable the import of the module :mod:`site` and the site-dependent
-   manipulations of :data:`sys.path` that it entails.  Also disable these
-   manipulations if :mod:`site` is explicitly imported later (call
-   :func:`site.main` if you want them to be triggered).
-
-   Set by the :option:`-S` option.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_NoUserSiteDirectory
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.user_site_directory` should be used instead, see
-   :ref:`Python Initialization Configuration <init-config>`.
-
-   Don't add the :data:`user site-packages directory <site.USER_SITE>` to
-   :data:`sys.path`.
-
-   Set by the :option:`-s` and :option:`-I` options, and the
-   :envvar:`PYTHONNOUSERSITE` environment variable.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_OptimizeFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.optimization_level` should be used instead, see
-   :ref:`Python Initialization Configuration <init-config>`.
-
-   Set by the :option:`-O` option and the :envvar:`PYTHONOPTIMIZE` environment
-   variable.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_QuietFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.quiet` should be used instead, see :ref:`Python
-   Initialization Configuration <init-config>`.
-
-   Don't display the copyright and version messages even in interactive mode.
-
-   Set by the :option:`-q` option.
-
-   .. versionadded:: 3.2
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_UnbufferedStdioFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.buffered_stdio` should be used instead, see :ref:`Python
-   Initialization Configuration <init-config>`.
-
-   Force the stdout and stderr streams to be unbuffered.
-
-   Set by the :option:`-u` option and the :envvar:`PYTHONUNBUFFERED`
-   environment variable.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
-.. c:var:: int Py_VerboseFlag
-
-   This API is kept for backward compatibility: setting
-   :c:member:`PyConfig.verbose` should be used instead, see :ref:`Python
-   Initialization Configuration <init-config>`.
-
-   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.
-
-   Set by the :option:`-v` option and the :envvar:`PYTHONVERBOSE` environment
-   variable.
-
-   .. deprecated-removed:: 3.12 3.16
-
-
 Initializing and finalizing the interpreter
 -------------------------------------------
 
diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat
index 662158323c5d305..82447cc98cd8d03 100644
--- a/Doc/data/stable_abi.dat
+++ b/Doc/data/stable_abi.dat
@@ -951,8 +951,6 @@ func,Py_EndInterpreter,3.2,,
 func,Py_EnterRecursiveCall,3.9,,
 func,Py_Exit,3.2,,
 func,Py_FatalError,3.2,,
-data,Py_FileSystemDefaultEncodeErrors,3.10,,
-data,Py_FileSystemDefaultEncoding,3.2,,
 func,Py_Finalize,3.2,,
 func,Py_FinalizeEx,3.6,,
 func,Py_GenericAlias,3.9,,
@@ -965,7 +963,6 @@ func,Py_GetCopyright,3.2,,
 func,Py_GetPlatform,3.2,,
 func,Py_GetRecursionLimit,3.2,,
 func,Py_GetVersion,3.2,,
-data,Py_HasFileSystemDefaultEncoding,3.2,,
 func,Py_HashBuffer,3.16,,
 func,Py_IS_TYPE,3.15,,
 func,Py_IncRef,3.2,,
@@ -1020,7 +1017,6 @@ macro,Py_T_ULONGLONG,3.12,,
 macro,Py_T_USHORT,3.12,,
 type,Py_UCS4,3.2,,
 macro,Py_UNBLOCK_THREADS,3.2,,
-data,Py_UTF8Mode,3.8,,
 func,Py_VaBuildValue,3.2,,
 data,Py_Version,3.11,,
 func,Py_XNewRef,3.10,,
diff --git a/Doc/deprecations/c-api-pending-removal-in-3.16.rst 
b/Doc/deprecations/c-api-pending-removal-in-3.16.rst
index fe2d91cf316b18f..dd840fac9b151b3 100644
--- a/Doc/deprecations/c-api-pending-removal-in-3.16.rst
+++ b/Doc/deprecations/c-api-pending-removal-in-3.16.rst
@@ -17,56 +17,56 @@ Pending removal in Python 3.16
 
 * Global configuration variables:
 
-  * :c:var:`Py_DebugFlag`:
+  * :c:var:`!Py_DebugFlag`:
     Use :c:member:`PyConfig.parser_debug` or
     :c:func:`PyConfig_Get("parser_debug") <PyConfig_Get>` instead.
-  * :c:var:`Py_VerboseFlag`:
+  * :c:var:`!Py_VerboseFlag`:
     Use :c:member:`PyConfig.verbose` or
     :c:func:`PyConfig_Get("verbose") <PyConfig_Get>` instead.
-  * :c:var:`Py_QuietFlag`:
+  * :c:var:`!Py_QuietFlag`:
     Use :c:member:`PyConfig.quiet` or
     :c:func:`PyConfig_Get("quiet") <PyConfig_Get>` instead.
-  * :c:var:`Py_InteractiveFlag`:
+  * :c:var:`!Py_InteractiveFlag`:
     Use :c:member:`PyConfig.interactive` or
     :c:func:`PyConfig_Get("interactive") <PyConfig_Get>` instead.
-  * :c:var:`Py_InspectFlag`:
+  * :c:var:`!Py_InspectFlag`:
     Use :c:member:`PyConfig.inspect` or
     :c:func:`PyConfig_Get("inspect") <PyConfig_Get>` instead.
-  * :c:var:`Py_OptimizeFlag`:
+  * :c:var:`!Py_OptimizeFlag`:
     Use :c:member:`PyConfig.optimization_level` or
     :c:func:`PyConfig_Get("optimization_level") <PyConfig_Get>` instead.
-  * :c:var:`Py_NoSiteFlag`:
+  * :c:var:`!Py_NoSiteFlag`:
     Use :c:member:`PyConfig.site_import` or
     :c:func:`PyConfig_Get("site_import") <PyConfig_Get>` instead.
-  * :c:var:`Py_BytesWarningFlag`:
+  * :c:var:`!Py_BytesWarningFlag`:
     Use :c:member:`PyConfig.bytes_warning` or
     :c:func:`PyConfig_Get("bytes_warning") <PyConfig_Get>` instead.
-  * :c:var:`Py_FrozenFlag`:
+  * :c:var:`!Py_FrozenFlag`:
     Use :c:member:`PyConfig.pathconfig_warnings` or
     :c:func:`PyConfig_Get("pathconfig_warnings") <PyConfig_Get>` instead.
-  * :c:var:`Py_IgnoreEnvironmentFlag`:
+  * :c:var:`!Py_IgnoreEnvironmentFlag`:
     Use :c:member:`PyConfig.use_environment` or
     :c:func:`PyConfig_Get("use_environment") <PyConfig_Get>` instead.
-  * :c:var:`Py_DontWriteBytecodeFlag`:
+  * :c:var:`!Py_DontWriteBytecodeFlag`:
     Use :c:member:`PyConfig.write_bytecode` or
     :c:func:`PyConfig_Get("write_bytecode") <PyConfig_Get>` instead.
-  * :c:var:`Py_NoUserSiteDirectory`:
+  * :c:var:`!Py_NoUserSiteDirectory`:
     Use :c:member:`PyConfig.user_site_directory` or
     :c:func:`PyConfig_Get("user_site_directory") <PyConfig_Get>` instead.
-  * :c:var:`Py_UnbufferedStdioFlag`:
+  * :c:var:`!Py_UnbufferedStdioFlag`:
     Use :c:member:`PyConfig.buffered_stdio` or
     :c:func:`PyConfig_Get("buffered_stdio") <PyConfig_Get>` instead.
-  * :c:var:`Py_HashRandomizationFlag`:
+  * :c:var:`!Py_HashRandomizationFlag`:
     Use :c:member:`PyConfig.use_hash_seed`
     and :c:member:`PyConfig.hash_seed` or
     :c:func:`PyConfig_Get("hash_seed") <PyConfig_Get>` instead.
-  * :c:var:`Py_IsolatedFlag`:
+  * :c:var:`!Py_IsolatedFlag`:
     Use :c:member:`PyConfig.isolated` or
     :c:func:`PyConfig_Get("isolated") <PyConfig_Get>` instead.
-  * :c:var:`Py_LegacyWindowsFSEncodingFlag`:
+  * :c:var:`!Py_LegacyWindowsFSEncodingFlag`:
     Use :c:member:`PyPreConfig.legacy_windows_fs_encoding` or
     :c:func:`PyConfig_Get("legacy_windows_fs_encoding") <PyConfig_Get>` 
instead.
-  * :c:var:`Py_LegacyWindowsStdioFlag`:
+  * :c:var:`!Py_LegacyWindowsStdioFlag`:
     Use :c:member:`PyConfig.legacy_windows_stdio` or
     :c:func:`PyConfig_Get("legacy_windows_stdio") <PyConfig_Get>` instead.
   * :c:var:`!Py_FileSystemDefaultEncoding`, 
:c:var:`!Py_HasFileSystemDefaultEncoding`:
diff --git a/Doc/tools/removed-ids.txt b/Doc/tools/removed-ids.txt
index eb2b30b7b4a1286..325cf006d0507e4 100644
--- a/Doc/tools/removed-ids.txt
+++ b/Doc/tools/removed-ids.txt
@@ -5,8 +5,27 @@ c-api/allocation.html: deprecated-aliases
 c-api/file.html: deprecated-api
 c-api/interp-lifecycle.html: c.PySys_SetArgv
 c-api/interp-lifecycle.html: c.PySys_SetArgvEx
+c-api/interp-lifecycle.html: c.Py_BytesWarningFlag
+c-api/interp-lifecycle.html: c.Py_DebugFlag
+c-api/interp-lifecycle.html: c.Py_DontWriteBytecodeFlag
+c-api/interp-lifecycle.html: c.Py_FrozenFlag
+c-api/interp-lifecycle.html: c.Py_HashRandomizationFlag
+c-api/interp-lifecycle.html: c.Py_IgnoreEnvironmentFlag
+c-api/interp-lifecycle.html: c.Py_InspectFlag
+c-api/interp-lifecycle.html: c.Py_InteractiveFlag
+c-api/interp-lifecycle.html: c.Py_IsolatedFlag
+c-api/interp-lifecycle.html: c.Py_LegacyWindowsFSEncodingFlag
+c-api/interp-lifecycle.html: c.Py_LegacyWindowsStdioFlag
+c-api/interp-lifecycle.html: c.Py_NoSiteFlag
+c-api/interp-lifecycle.html: c.Py_NoUserSiteDirectory
+c-api/interp-lifecycle.html: c.Py_OptimizeFlag
+c-api/interp-lifecycle.html: c.Py_QuietFlag
 c-api/interp-lifecycle.html: c.Py_SetProgramName
 c-api/interp-lifecycle.html: c.Py_SetPythonHome
+c-api/interp-lifecycle.html: c.Py_UnbufferedStdioFlag
+c-api/interp-lifecycle.html: c.Py_VerboseFlag
+c-api/interp-lifecycle.html: global-conf-vars
+c-api/interp-lifecycle.html: global-configuration-variables
 c-api/threads.html: c.PyEval_InitThreads
 
 # Removed sections
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 9e48b3ab7393c87..78ddc627fcf4d70 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -2170,24 +2170,24 @@ Deprecated
 
 * Deprecate global configuration variable:
 
-  * :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug`
-  * :c:var:`Py_VerboseFlag`: use :c:member:`PyConfig.verbose`
-  * :c:var:`Py_QuietFlag`: use :c:member:`PyConfig.quiet`
-  * :c:var:`Py_InteractiveFlag`: use :c:member:`PyConfig.interactive`
-  * :c:var:`Py_InspectFlag`: use :c:member:`PyConfig.inspect`
-  * :c:var:`Py_OptimizeFlag`: use :c:member:`PyConfig.optimization_level`
-  * :c:var:`Py_NoSiteFlag`: use :c:member:`PyConfig.site_import`
-  * :c:var:`Py_BytesWarningFlag`: use :c:member:`PyConfig.bytes_warning`
-  * :c:var:`Py_FrozenFlag`: use :c:member:`PyConfig.pathconfig_warnings`
-  * :c:var:`Py_IgnoreEnvironmentFlag`: use :c:member:`PyConfig.use_environment`
-  * :c:var:`Py_DontWriteBytecodeFlag`: use :c:member:`PyConfig.write_bytecode`
-  * :c:var:`Py_NoUserSiteDirectory`: use 
:c:member:`PyConfig.user_site_directory`
-  * :c:var:`Py_UnbufferedStdioFlag`: use :c:member:`PyConfig.buffered_stdio`
-  * :c:var:`Py_HashRandomizationFlag`: use :c:member:`PyConfig.use_hash_seed`
+  * :c:var:`!Py_DebugFlag`: use :c:member:`PyConfig.parser_debug`
+  * :c:var:`!Py_VerboseFlag`: use :c:member:`PyConfig.verbose`
+  * :c:var:`!Py_QuietFlag`: use :c:member:`PyConfig.quiet`
+  * :c:var:`!Py_InteractiveFlag`: use :c:member:`PyConfig.interactive`
+  * :c:var:`!Py_InspectFlag`: use :c:member:`PyConfig.inspect`
+  * :c:var:`!Py_OptimizeFlag`: use :c:member:`PyConfig.optimization_level`
+  * :c:var:`!Py_NoSiteFlag`: use :c:member:`PyConfig.site_import`
+  * :c:var:`!Py_BytesWarningFlag`: use :c:member:`PyConfig.bytes_warning`
+  * :c:var:`!Py_FrozenFlag`: use :c:member:`PyConfig.pathconfig_warnings`
+  * :c:var:`!Py_IgnoreEnvironmentFlag`: use 
:c:member:`PyConfig.use_environment`
+  * :c:var:`!Py_DontWriteBytecodeFlag`: use :c:member:`PyConfig.write_bytecode`
+  * :c:var:`!Py_NoUserSiteDirectory`: use 
:c:member:`PyConfig.user_site_directory`
+  * :c:var:`!Py_UnbufferedStdioFlag`: use :c:member:`PyConfig.buffered_stdio`
+  * :c:var:`!Py_HashRandomizationFlag`: use :c:member:`PyConfig.use_hash_seed`
     and :c:member:`PyConfig.hash_seed`
-  * :c:var:`Py_IsolatedFlag`: use :c:member:`PyConfig.isolated`
-  * :c:var:`Py_LegacyWindowsFSEncodingFlag`: use 
:c:member:`PyPreConfig.legacy_windows_fs_encoding`
-  * :c:var:`Py_LegacyWindowsStdioFlag`: use 
:c:member:`PyConfig.legacy_windows_stdio`
+  * :c:var:`!Py_IsolatedFlag`: use :c:member:`PyConfig.isolated`
+  * :c:var:`!Py_LegacyWindowsFSEncodingFlag`: use 
:c:member:`PyPreConfig.legacy_windows_fs_encoding`
+  * :c:var:`!Py_LegacyWindowsStdioFlag`: use 
:c:member:`PyConfig.legacy_windows_stdio`
   * :c:var:`!Py_FileSystemDefaultEncoding`: use 
:c:member:`PyConfig.filesystem_encoding`
   * :c:var:`!Py_HasFileSystemDefaultEncoding`: use 
:c:member:`PyConfig.filesystem_encoding`
   * :c:var:`!Py_FileSystemDefaultEncodeErrors`: use 
:c:member:`PyConfig.filesystem_errors`
diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst
index c76681261f6746d..fe9f3028eab2b1c 100644
--- a/Doc/whatsnew/3.16.rst
+++ b/Doc/whatsnew/3.16.rst
@@ -1141,6 +1141,37 @@ Deprecated C APIs
 Removed C APIs
 --------------
 
+* Remove 21 global configuration variables, deprecated in Python 3.12.
+  To initialize Python, the :ref:`PyInitConfig C API <pyinitconfig_api>` can be
+  used instead.
+  To read these variables at runtime, :c:func:`PyConfig_Get` can be used
+  instead.
+  Removed variables with their :ref:`PyInitConfig C API <pyinitconfig_api>` and
+  :c:func:`PyConfig_Get` replacement:
+
+  * :c:var:`!Py_DebugFlag`: Use ``"parser_debug"`` instead.
+  * :c:var:`!Py_VerboseFlag`: Use ``"verbose"`` instead.
+  * :c:var:`!Py_QuietFlag`: Use ``"quiet"`` instead.
+  * :c:var:`!Py_InteractiveFlag`: Use ``"interactive"`` instead.
+  * :c:var:`!Py_InspectFlag`: Use ``"inspect"`` instead.
+  * :c:var:`!Py_OptimizeFlag`: Use ``"optimization_level"`` instead.
+  * :c:var:`!Py_NoSiteFlag`: Use ``"site_import"`` instead (opposite value).
+  * :c:var:`!Py_BytesWarningFlag`: Use ``"bytes_warning"`` instead.
+  * :c:var:`!Py_FrozenFlag`: Use ``"pathconfig_warnings"`` instead (opposite 
value).
+  * :c:var:`!Py_IgnoreEnvironmentFlag`: Use ``"use_environment"`` instead 
(opposite value).
+  * :c:var:`!Py_DontWriteBytecodeFlag`: Use ``"write_bytecode"`` instead 
(opposite value).
+  * :c:var:`!Py_NoUserSiteDirectory`: Use ``"user_site_directory"`` instead 
(opposite value).
+  * :c:var:`!Py_UnbufferedStdioFlag`: Use ``"buffered_stdio"`` instead 
(opposite value).
+  * :c:var:`!Py_HashRandomizationFlag`: Use ``"hash_seed"`` instead.
+  * :c:var:`!Py_IsolatedFlag`: Use ``"isolated"`` instead.
+  * :c:var:`!Py_LegacyWindowsFSEncodingFlag`: Use 
``"legacy_windows_fs_encoding"`` instead.
+  * :c:var:`!Py_LegacyWindowsStdioFlag`: Use ``"legacy_windows_stdio"`` 
instead.
+  * :c:var:`!Py_FileSystemDefaultEncoding`, 
:c:var:`!Py_HasFileSystemDefaultEncoding`: Use ``"filesystem_encoding"`` 
instead.
+  * :c:var:`!Py_FileSystemDefaultEncodeErrors`: Use ``"filesystem_errors"`` 
instead.
+  * :c:var:`!Py_UTF8Mode`: Use ``"utf8_mode"`` instead.
+
+  (Contributed by Victor Stinner in :gh:`158001`.)
+
 * Remove :c:func:`!PyEval_InitThreads` function which did nothing since Python
   3.7 and was deprecated since Python 3.9.
   (Contributed by Victor Stinner in :gh:`154757`.)
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index 3af3e6ec9cac08f..6900c97e9546c9a 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/whatsnew/3.7.rst
@@ -2524,7 +2524,7 @@ number of other issues). Some known details affected:
   over the default filters set by the interpreter
 
 Due to changes in the way the default warnings filters are configured,
-setting :c:data:`Py_BytesWarningFlag` to a value greater than one is no longer
+setting :c:data:`!Py_BytesWarningFlag` to a value greater than one is no longer
 sufficient to both emit :exc:`BytesWarning` messages and have them converted
 to exceptions.  Instead, the flag must be set (to cause the warnings to be
 emitted in the first place), and an explicit ``error::BytesWarning``
@@ -2547,7 +2547,7 @@ Starting in 3.7.1, :c:func:`Py_Initialize` now 
consistently reads and respects
 all of the same environment settings as :c:func:`Py_Main` (in earlier Python
 versions, it respected an ill-defined subset of those environment variables,
 while in Python 3.7.0 it didn't read any of them due to :issue:`34247`). If
-this behavior is unwanted, set :c:data:`Py_IgnoreEnvironmentFlag` to 1 before
+this behavior is unwanted, set :c:data:`!Py_IgnoreEnvironmentFlag` to 1 before
 calling :c:func:`Py_Initialize`.
 
 In 3.7.1 the C API for Context Variables
diff --git a/Include/cpython/pydebug.h b/Include/cpython/pydebug.h
index f6ebd99ed7e2ff2..d27f992f4601099 100644
--- a/Include/cpython/pydebug.h
+++ b/Include/cpython/pydebug.h
@@ -5,27 +5,6 @@
 extern "C" {
 #endif
 
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_DebugFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_VerboseFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_QuietFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_InteractiveFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_InspectFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_OptimizeFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoSiteFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_BytesWarningFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_FrozenFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_DontWriteBytecodeFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoUserSiteDirectory;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_UnbufferedStdioFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_HashRandomizationFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_IsolatedFlag;
-
-#ifdef MS_WINDOWS
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag;
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_LegacyWindowsStdioFlag;
-#endif
-
 /* this is a wrapper around getenv() that pays attention to
    Py_IgnoreEnvironmentFlag.  It should be used for getting variables like
    PYTHONPATH and PYTHONHOME from the environment */
diff --git a/Include/fileobject.h b/Include/fileobject.h
index 6a6d11409497fab..464bc3b29f483ad 100644
--- a/Include/fileobject.h
+++ b/Include/fileobject.h
@@ -16,19 +16,6 @@ PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, 
int);
 PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *);
 PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *);
 
-/* The default encoding used by the platform file system APIs
-   If non-NULL, this is different than the default encoding for strings
-*/
-Py_DEPRECATED(3.12) PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
-#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000
-Py_DEPRECATED(3.12) PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors;
-#endif
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding;
-
-#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
-Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_UTF8Mode;
-#endif
-
 #ifndef Py_LIMITED_API
 #  define Py_CPYTHON_FILEOBJECT_H
 #  include "cpython/fileobject.h"
diff --git a/Include/internal/pycore_fileutils.h 
b/Include/internal/pycore_fileutils.h
index 83cdc4f3dfdd44a..128790823aa8794 100644
--- a/Include/internal/pycore_fileutils.h
+++ b/Include/internal/pycore_fileutils.h
@@ -190,8 +190,6 @@ extern int _Py_open_osfhandle(void *handle, int flags);
      ? _PyStatus_ERR("cannot decode " NAME) \
      : _PyStatus_NO_MEMORY()
 
-extern int _Py_HasFileSystemDefaultEncodeErrors;
-
 extern int _Py_DecodeUTF8Ex(
     const char *arg,
     Py_ssize_t arglen,
diff --git a/Lib/test/test_capi/test_config.py 
b/Lib/test/test_capi/test_config.py
index 290126343618381..789f652b004bffb 100644
--- a/Lib/test/test_capi/test_config.py
+++ b/Lib/test/test_capi/test_config.py
@@ -379,46 +379,6 @@ def expect_bool_not(value):
                 finally:
                     config_set(name, old_value)
 
-    def test_config_set_global_vars(self):
-        # Test PyConfig_Set() with global configuration variables
-        config_get = _testcapi.config_get
-        config_set = _testcapi.config_set
-        get_configs = _testinternalcapi.get_configs
-        new_values = (0, 1, 5)
-
-        for name, global_name, not_value in (
-            ('bytes_warning', 'Py_BytesWarningFlag', False),
-            ('inspect', 'Py_InspectFlag', False),
-            ('interactive', 'Py_InteractiveFlag', False),
-            ('optimization_level', 'Py_OptimizeFlag', False),
-            ('parser_debug', 'Py_DebugFlag', False),
-            ('quiet', 'Py_QuietFlag', False),
-            ('use_environment', 'Py_IgnoreEnvironmentFlag', True),
-            ('verbose', 'Py_VerboseFlag', False),
-            ('write_bytecode', 'Py_DontWriteBytecodeFlag', True),
-
-            # Read-only variables
-            #('buffered_stdio', 'Py_UnbufferedStdioFlag', True),
-            #('isolated', 'Py_IsolatedFlag', False),
-            #('pathconfig_warnings', 'Py_FrozenFlag', True),
-            #('site_import', 'Py_NoSiteFlag', True),
-            #('user_site_directory', 'Py_NoUserSiteDirectory', True),
-            # Windows only
-            #('legacy_windows_stdio', 'Py_LegacyWindowsStdioFlag', False)
-        ):
-            with self.subTest(name=name):
-                old_value = config_get(name)
-                try:
-                    for value in new_values:
-                        config_set(name, value)
-                        global_config = get_configs()['global_config']
-                        expected = value
-                        if not_value:
-                            expected = int(not value)
-                        self.assertEqual(global_config[global_name], expected)
-                finally:
-                    config_set(name, old_value)
-
     def test_config_set_cpu_count(self):
         config_get = _testcapi.config_get
         config_set = _testcapi.config_set
diff --git a/Lib/test/test_ctypes/test_values.py 
b/Lib/test/test_ctypes/test_values.py
index 82c928c9f6406c2..0d62702c0c0fd35 100644
--- a/Lib/test/test_ctypes/test_values.py
+++ b/Lib/test/test_ctypes/test_values.py
@@ -73,12 +73,12 @@ def test_undefined(self):
 class PythonValuesTestCase(unittest.TestCase):
     """This test only works when python itself is a dll/shared library"""
 
-    def test_optimizeflag(self):
-        # This test accesses the Py_OptimizeFlag integer, which is
-        # exported by the Python dll and should match the sys.flags value
+    def test_version_var(self):
+        # This test accesses the Py_Version integer, which is
+        # exported by the Python dll and should match the sys.hexversion value
 
-        opt = c_int.in_dll(pythonapi, "Py_OptimizeFlag").value
-        self.assertEqual(opt, sys.flags.optimize)
+        version = c_int.in_dll(pythonapi, "Py_Version").value
+        self.assertEqual(version, sys.hexversion)
 
     @thread_unsafe('overrides frozen modules')
     def test_frozentable(self):
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index 81241ea1f337336..77b231323cc2757 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -823,7 +823,6 @@ class InitConfigTests(EmbeddingTestsMixin, 
unittest.TestCase):
     # global config
     DEFAULT_GLOBAL_CONFIG = {
         'Py_HasFileSystemDefaultEncoding': 0,
-        'Py_HashRandomizationFlag': 1,
         '_Py_HasFileSystemDefaultEncodeErrors': 0,
     }
     COPY_GLOBAL_PRE_CONFIG = [
@@ -831,31 +830,9 @@ class InitConfigTests(EmbeddingTestsMixin, 
unittest.TestCase):
     ]
     COPY_GLOBAL_CONFIG = [
         # Copy core config to global config for expected values
-        # True means that the core config value is inverted (0 => 1 and 1 => 0)
-        ('Py_BytesWarningFlag', 'bytes_warning'),
-        ('Py_DebugFlag', 'parser_debug'),
-        ('Py_DontWriteBytecodeFlag', 'write_bytecode', True),
         ('Py_FileSystemDefaultEncodeErrors', 'filesystem_errors'),
         ('Py_FileSystemDefaultEncoding', 'filesystem_encoding'),
-        ('Py_FrozenFlag', 'pathconfig_warnings', True),
-        ('Py_IgnoreEnvironmentFlag', 'use_environment', True),
-        ('Py_InspectFlag', 'inspect'),
-        ('Py_InteractiveFlag', 'interactive'),
-        ('Py_IsolatedFlag', 'isolated'),
-        ('Py_NoSiteFlag', 'site_import', True),
-        ('Py_NoUserSiteDirectory', 'user_site_directory', True),
-        ('Py_OptimizeFlag', 'optimization_level'),
-        ('Py_QuietFlag', 'quiet'),
-        ('Py_UnbufferedStdioFlag', 'buffered_stdio', True),
-        ('Py_VerboseFlag', 'verbose'),
     ]
-    if MS_WINDOWS:
-        COPY_GLOBAL_PRE_CONFIG.extend((
-            ('Py_LegacyWindowsFSEncodingFlag', 'legacy_windows_fs_encoding'),
-        ))
-        COPY_GLOBAL_CONFIG.extend((
-            ('Py_LegacyWindowsStdioFlag', 'legacy_windows_stdio'),
-        ))
 
     EXPECTED_CONFIG = None
 
@@ -1013,20 +990,10 @@ def check_global_config(self, configs):
         config = configs['config']
 
         expected = dict(self.DEFAULT_GLOBAL_CONFIG)
-        for item in self.COPY_GLOBAL_CONFIG:
-            if len(item) == 3:
-                global_key, core_key, opposite = item
-                expected[global_key] = 0 if config[core_key] else 1
-            else:
-                global_key, core_key = item
-                expected[global_key] = config[core_key]
-        for item in self.COPY_GLOBAL_PRE_CONFIG:
-            if len(item) == 3:
-                global_key, core_key, opposite = item
-                expected[global_key] = 0 if pre_config[core_key] else 1
-            else:
-                global_key, core_key = item
-                expected[global_key] = pre_config[core_key]
+        for global_key, core_key in self.COPY_GLOBAL_CONFIG:
+            expected[global_key] = config[core_key]
+        for global_key, core_key in self.COPY_GLOBAL_PRE_CONFIG:
+            expected[global_key] = pre_config[core_key]
 
         self.assertEqual(configs['global_config'], expected)
 
diff --git 
a/Misc/NEWS.d/next/C_API/2026-07-08-00-38-32.gh-issue-153300.lVoWyR.rst 
b/Misc/NEWS.d/next/C_API/2026-07-08-00-38-32.gh-issue-153300.lVoWyR.rst
index 3c19c0e15d2bc65..bb85114220bbe63 100644
--- a/Misc/NEWS.d/next/C_API/2026-07-08-00-38-32.gh-issue-153300.lVoWyR.rst
+++ b/Misc/NEWS.d/next/C_API/2026-07-08-00-38-32.gh-issue-153300.lVoWyR.rst
@@ -1,3 +1,3 @@
 :c:func:`PyConfig_Set()` now also set global configuration variables. For
 example, ``PyConfig_Set("inspect", value)`` now also sets
-:c:var:`Py_InspectFlag`. Patch by Victor Stinner.
+:c:var:`!Py_InspectFlag`. Patch by Victor Stinner.
diff --git 
a/Misc/NEWS.d/next/C_API/2026-09-23-19-37-53.gh-issue-158001.X_Xamm.rst 
b/Misc/NEWS.d/next/C_API/2026-09-23-19-37-53.gh-issue-158001.X_Xamm.rst
new file mode 100644
index 000000000000000..1b81be97e283eac
--- /dev/null
+++ b/Misc/NEWS.d/next/C_API/2026-09-23-19-37-53.gh-issue-158001.X_Xamm.rst
@@ -0,0 +1,25 @@
+Remove 21 global configuration variables:
+
+* :c:var:`!Py_BytesWarningFlag`,
+* :c:var:`!Py_DebugFlag`,
+* :c:var:`!Py_DontWriteBytecodeFlag`,
+* :c:var:`!Py_FileSystemDefaultEncodeErrors`,
+* :c:var:`!Py_FileSystemDefaultEncoding`,
+* :c:var:`!Py_FrozenFlag`,
+* :c:var:`!Py_HasFileSystemDefaultEncoding`,
+* :c:var:`!Py_HashRandomizationFlag`,
+* :c:var:`!Py_IgnoreEnvironmentFlag`,
+* :c:var:`!Py_InspectFlag`,
+* :c:var:`!Py_InteractiveFlag`,
+* :c:var:`!Py_IsolatedFlag`,
+* :c:var:`!Py_LegacyWindowsFSEncodingFlag`,
+* :c:var:`!Py_LegacyWindowsStdioFlag`,
+* :c:var:`!Py_NoSiteFlag`,
+* :c:var:`!Py_NoUserSiteDirectory`,
+* :c:var:`!Py_OptimizeFlag`,
+* :c:var:`!Py_QuietFlag`,
+* :c:var:`!Py_UTF8Mode`,
+* :c:var:`!Py_UnbufferedStdioFlag`,
+* :c:var:`!Py_VerboseFlag`.
+
+Patch by Victor Stinner.
diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml
index 08fd7009dbc4b86..0425fba42cbe2c7 100644
--- a/Misc/stable_abi.toml
+++ b/Misc/stable_abi.toml
@@ -1643,6 +1643,7 @@
     added = '3.2'
 [data.Py_FileSystemDefaultEncoding]
     added = '3.2'
+    abi_only = true
 [function.Py_Finalize]
     added = '3.2'
 [function.Py_GetBuildInfo]
@@ -1677,6 +1678,7 @@
     added = '3.2'
 [data.Py_HasFileSystemDefaultEncoding]
     added = '3.2'
+    abi_only = true
 [function.Py_IncRef]
     added = '3.2'
 [function.Py_Initialize]
@@ -2178,6 +2180,7 @@
     added = '3.8'
 [data.Py_UTF8Mode]
     added = '3.8'
+    abi_only = true
 [function.PyExceptionClass_Name]
     added = '3.8'
 [function.PyIndex_Check]
@@ -2264,6 +2267,7 @@
     added = '3.10'
 [data.Py_FileSystemDefaultEncodeErrors]
     added = '3.10'
+    abi_only = true
 [function.PyCodec_Unregister]
     added = '3.10'
 [function.PyErr_SetInterruptEx]
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index 7e82a6365d9808b..79e817829c15947 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -31,6 +31,9 @@ extern void Py_SetPythonHome(const wchar_t *);
 // for the stable ABI. We want to test them in this program.
 extern void PySys_ResetWarnOptions(void);
 
+// Variable removed from Python 3.16 limited C API, but kept in the stable ABI
+PyAPI_DATA(int) Py_UTF8Mode;
+
 
 int main_argc;
 char **main_argv;
diff --git a/Python/initconfig.c b/Python/initconfig.c
index 464c76f9e3df2fc..d683fdd6abc6e1b 100644
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -95,128 +95,115 @@ typedef struct {
     PyConfigMemberType type;
     PyConfigMemberVisibility visibility;
     PyConfigSysSpec sys;
-    PyConfigGlobalVar global_var;
 } PyConfigSpec;
 
-#define SPEC(MEMBER, TYPE, VISIBILITY, sys, global_var) \
+#define SPEC(MEMBER, TYPE, VISIBILITY, sys) \
     {#MEMBER, offsetof(PyConfig, MEMBER), \
-     PyConfig_MEMBER_##TYPE, PyConfig_MEMBER_##VISIBILITY, sys, global_var}
+     PyConfig_MEMBER_##TYPE, PyConfig_MEMBER_##VISIBILITY, sys}
 
 #define SYS_ATTR(name) {name, -1, NULL}
 #define SYS_FLAG_SETTER(index, setter) {NULL, index, setter}
 #define SYS_FLAG(index) SYS_FLAG_SETTER(index, NULL)
 #define NO_SYS SYS_ATTR(NULL)
 
-#define GLOBAL(ptr, not) {ptr, not}
-#define NO_GLOBAL GLOBAL(NULL, 0)
-
-// Ignore deprecations on global variables such as Py_IsolatedFlag
-_Py_COMP_DIAG_PUSH
-_Py_COMP_DIAG_IGNORE_DEPR_DECLS
-
 // Update _test_embed_set_config when adding new members
 static const PyConfigSpec PYCONFIG_SPEC[] = {
     // --- Public options -----------
 
-    SPEC(argv, WSTR_LIST, PUBLIC, SYS_ATTR("argv"), NO_GLOBAL),
-    SPEC(base_exec_prefix, WSTR_OPT, PUBLIC, SYS_ATTR("base_exec_prefix"), 
NO_GLOBAL),
-    SPEC(base_executable, WSTR_OPT, PUBLIC, SYS_ATTR("_base_executable"), 
NO_GLOBAL),
-    SPEC(base_prefix, WSTR_OPT, PUBLIC, SYS_ATTR("base_prefix"), NO_GLOBAL),
-    SPEC(bytes_warning, UINT, PUBLIC, SYS_FLAG(9), 
GLOBAL(&Py_BytesWarningFlag, 0)),
-    SPEC(cpu_count, INT, PUBLIC, NO_SYS, NO_GLOBAL),
-    SPEC(lazy_imports, INT, PUBLIC, NO_SYS, NO_GLOBAL),
-    SPEC(exec_prefix, WSTR_OPT, PUBLIC, SYS_ATTR("exec_prefix"), NO_GLOBAL),
-    SPEC(executable, WSTR_OPT, PUBLIC, SYS_ATTR("executable"), NO_GLOBAL),
-    SPEC(inspect, BOOL, PUBLIC, SYS_FLAG(1), GLOBAL(&Py_InspectFlag, 0)),
-    SPEC(int_max_str_digits, UINT, PUBLIC, NO_SYS, NO_GLOBAL),
-    SPEC(interactive, BOOL, PUBLIC, SYS_FLAG(2), GLOBAL(&Py_InteractiveFlag, 
0)),
-    SPEC(module_search_paths, WSTR_LIST, PUBLIC, SYS_ATTR("path"), NO_GLOBAL),
-    SPEC(optimization_level, UINT, PUBLIC, SYS_FLAG(3), 
GLOBAL(&Py_OptimizeFlag, 0)),
-    SPEC(parser_debug, BOOL, PUBLIC, SYS_FLAG(0), GLOBAL(&Py_DebugFlag, 0)),
-    SPEC(platlibdir, WSTR, PUBLIC, SYS_ATTR("platlibdir"), NO_GLOBAL),
-    SPEC(prefix, WSTR_OPT, PUBLIC, SYS_ATTR("prefix"), NO_GLOBAL),
-    SPEC(pycache_prefix, WSTR_OPT, PUBLIC, SYS_ATTR("pycache_prefix"), 
NO_GLOBAL),
-    SPEC(quiet, BOOL, PUBLIC, SYS_FLAG(10), GLOBAL(&Py_QuietFlag, 0)),
-    SPEC(stdlib_dir, WSTR_OPT, PUBLIC, SYS_ATTR("_stdlib_dir"), NO_GLOBAL),
+    SPEC(argv, WSTR_LIST, PUBLIC, SYS_ATTR("argv")),
+    SPEC(base_exec_prefix, WSTR_OPT, PUBLIC, SYS_ATTR("base_exec_prefix")),
+    SPEC(base_executable, WSTR_OPT, PUBLIC, SYS_ATTR("_base_executable")),
+    SPEC(base_prefix, WSTR_OPT, PUBLIC, SYS_ATTR("base_prefix")),
+    SPEC(bytes_warning, UINT, PUBLIC, SYS_FLAG(9)),
+    SPEC(cpu_count, INT, PUBLIC, NO_SYS),
+    SPEC(lazy_imports, INT, PUBLIC, NO_SYS),
+    SPEC(exec_prefix, WSTR_OPT, PUBLIC, SYS_ATTR("exec_prefix")),
+    SPEC(executable, WSTR_OPT, PUBLIC, SYS_ATTR("executable")),
+    SPEC(inspect, BOOL, PUBLIC, SYS_FLAG(1)),
+    SPEC(int_max_str_digits, UINT, PUBLIC, NO_SYS),
+    SPEC(interactive, BOOL, PUBLIC, SYS_FLAG(2)),
+    SPEC(module_search_paths, WSTR_LIST, PUBLIC, SYS_ATTR("path")),
+    SPEC(optimization_level, UINT, PUBLIC, SYS_FLAG(3)),
+    SPEC(parser_debug, BOOL, PUBLIC, SYS_FLAG(0)),
+    SPEC(platlibdir, WSTR, PUBLIC, SYS_ATTR("platlibdir")),
+    SPEC(prefix, WSTR_OPT, PUBLIC, SYS_ATTR("prefix")),
+    SPEC(pycache_prefix, WSTR_OPT, PUBLIC, SYS_ATTR("pycache_prefix")),
+    SPEC(quiet, BOOL, PUBLIC, SYS_FLAG(10)),
+    SPEC(stdlib_dir, WSTR_OPT, PUBLIC, SYS_ATTR("_stdlib_dir")),
     SPEC(use_environment, BOOL, PUBLIC,
-         SYS_FLAG_SETTER(7, config_sys_flag_not), 
GLOBAL(&Py_IgnoreEnvironmentFlag, 1)),
-    SPEC(verbose, UINT, PUBLIC, SYS_FLAG(8), GLOBAL(&Py_VerboseFlag, 0)),
-    SPEC(warnoptions, WSTR_LIST, PUBLIC, SYS_ATTR("warnoptions"), NO_GLOBAL),
-    SPEC(write_bytecode, BOOL, PUBLIC, SYS_FLAG_SETTER(4, config_sys_flag_not),
-         GLOBAL(&Py_DontWriteBytecodeFlag, 1)),
-    SPEC(xoptions, WSTR_LIST, PUBLIC, SYS_ATTR("_xoptions"), NO_GLOBAL),
+         SYS_FLAG_SETTER(7, config_sys_flag_not)),
+    SPEC(verbose, UINT, PUBLIC, SYS_FLAG(8)),
+    SPEC(warnoptions, WSTR_LIST, PUBLIC, SYS_ATTR("warnoptions")),
+    SPEC(write_bytecode, BOOL, PUBLIC, SYS_FLAG_SETTER(4, 
config_sys_flag_not)),
+    SPEC(xoptions, WSTR_LIST, PUBLIC, SYS_ATTR("_xoptions")),
 
     // --- Read-only options -----------
 
 #ifdef Py_STATS
-    SPEC(_pystats, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
+    SPEC(_pystats, BOOL, READ_ONLY, NO_SYS),
 #endif
-    SPEC(buffered_stdio, BOOL, READ_ONLY, NO_SYS,
-         GLOBAL(&Py_UnbufferedStdioFlag, 1)),
-    SPEC(check_hash_pycs_mode, WSTR, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(code_debug_ranges, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(configure_c_stdio, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(dev_mode, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),  // sys.flags.dev_mode
-    SPEC(dump_refs, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(dump_refs_file, WSTR_OPT, READ_ONLY, NO_SYS, NO_GLOBAL),
+    SPEC(buffered_stdio, BOOL, READ_ONLY, NO_SYS),
+    SPEC(check_hash_pycs_mode, WSTR, READ_ONLY, NO_SYS),
+    SPEC(code_debug_ranges, BOOL, READ_ONLY, NO_SYS),
+    SPEC(configure_c_stdio, BOOL, READ_ONLY, NO_SYS),
+    SPEC(dev_mode, BOOL, READ_ONLY, NO_SYS),  // sys.flags.dev_mode
+    SPEC(dump_refs, BOOL, READ_ONLY, NO_SYS),
+    SPEC(dump_refs_file, WSTR_OPT, READ_ONLY, NO_SYS),
 #ifdef Py_GIL_DISABLED
-    SPEC(enable_gil, INT, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(tlbc_enabled, INT, READ_ONLY, NO_SYS, NO_GLOBAL),
+    SPEC(enable_gil, INT, READ_ONLY, NO_SYS),
+    SPEC(tlbc_enabled, INT, READ_ONLY, NO_SYS),
 #endif
-    SPEC(faulthandler, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(filesystem_encoding, WSTR, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(filesystem_errors, WSTR, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(hash_seed, ULONG, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(home, WSTR_OPT, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(thread_inherit_context, INT, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(context_aware_warnings, INT, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(import_time, UINT, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(install_signal_handlers, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(isolated, BOOL, READ_ONLY, NO_SYS, GLOBAL(&Py_IsolatedFlag, 0)),  // 
sys.flags.isolated
+    SPEC(faulthandler, BOOL, READ_ONLY, NO_SYS),
+    SPEC(filesystem_encoding, WSTR, READ_ONLY, NO_SYS),
+    SPEC(filesystem_errors, WSTR, READ_ONLY, NO_SYS),
+    SPEC(hash_seed, ULONG, READ_ONLY, NO_SYS),
+    SPEC(home, WSTR_OPT, READ_ONLY, NO_SYS),
+    SPEC(thread_inherit_context, INT, READ_ONLY, NO_SYS),
+    SPEC(context_aware_warnings, INT, READ_ONLY, NO_SYS),
+    SPEC(import_time, UINT, READ_ONLY, NO_SYS),
+    SPEC(install_signal_handlers, BOOL, READ_ONLY, NO_SYS),
+    SPEC(isolated, BOOL, READ_ONLY, NO_SYS),  // sys.flags.isolated
 #ifdef MS_WINDOWS
-    SPEC(legacy_windows_stdio, BOOL, READ_ONLY, NO_SYS,
-         GLOBAL(&Py_LegacyWindowsStdioFlag, 0)),
+    SPEC(legacy_windows_stdio, BOOL, READ_ONLY, NO_SYS),
 #endif
-    SPEC(malloc_stats, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(pymalloc_hugepages, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(orig_argv, WSTR_LIST, READ_ONLY, SYS_ATTR("orig_argv"), NO_GLOBAL),
-    SPEC(parse_argv, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(pathconfig_warnings, BOOL, READ_ONLY, NO_SYS,
-         GLOBAL(&Py_FrozenFlag, 1)),
-    SPEC(perf_profiling, UINT, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(remote_debug, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(program_name, WSTR, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(run_command, WSTR_OPT, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(run_filename, WSTR_OPT, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(run_module, WSTR_OPT, READ_ONLY, NO_SYS, NO_GLOBAL),
+    SPEC(malloc_stats, BOOL, READ_ONLY, NO_SYS),
+    SPEC(pymalloc_hugepages, BOOL, READ_ONLY, NO_SYS),
+    SPEC(orig_argv, WSTR_LIST, READ_ONLY, SYS_ATTR("orig_argv")),
+    SPEC(parse_argv, BOOL, READ_ONLY, NO_SYS),
+    SPEC(pathconfig_warnings, BOOL, READ_ONLY, NO_SYS),
+    SPEC(perf_profiling, UINT, READ_ONLY, NO_SYS),
+    SPEC(remote_debug, BOOL, READ_ONLY, NO_SYS),
+    SPEC(program_name, WSTR, READ_ONLY, NO_SYS),
+    SPEC(run_command, WSTR_OPT, READ_ONLY, NO_SYS),
+    SPEC(run_filename, WSTR_OPT, READ_ONLY, NO_SYS),
+    SPEC(run_module, WSTR_OPT, READ_ONLY, NO_SYS),
 #ifdef Py_DEBUG
-    SPEC(run_presite, WSTR_OPT, READ_ONLY, NO_SYS, NO_GLOBAL),
+    SPEC(run_presite, WSTR_OPT, READ_ONLY, NO_SYS),
 #endif
-    SPEC(safe_path, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(show_ref_count, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(site_import, BOOL, READ_ONLY, NO_SYS, GLOBAL(&Py_NoSiteFlag, 1)),  // 
sys.flags.no_site
-    SPEC(skip_source_first_line, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(stdio_encoding, WSTR_OPT, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(stdio_errors, WSTR, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(tracemalloc, UINT, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(use_frozen_modules, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(use_hash_seed, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
+    SPEC(safe_path, BOOL, READ_ONLY, NO_SYS),
+    SPEC(show_ref_count, BOOL, READ_ONLY, NO_SYS),
+    SPEC(site_import, BOOL, READ_ONLY, NO_SYS),  // sys.flags.no_site
+    SPEC(skip_source_first_line, BOOL, READ_ONLY, NO_SYS),
+    SPEC(stdio_encoding, WSTR_OPT, READ_ONLY, NO_SYS),
+    SPEC(stdio_errors, WSTR, READ_ONLY, NO_SYS),
+    SPEC(tracemalloc, UINT, READ_ONLY, NO_SYS),
+    SPEC(use_frozen_modules, BOOL, READ_ONLY, NO_SYS),
+    SPEC(use_hash_seed, BOOL, READ_ONLY, NO_SYS),
 #ifdef __APPLE__
-    SPEC(use_system_logger, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
+    SPEC(use_system_logger, BOOL, READ_ONLY, NO_SYS),
 #endif
-    SPEC(user_site_directory, BOOL, READ_ONLY, NO_SYS,
-         GLOBAL(&Py_NoUserSiteDirectory, 1)),  // sys.flags.no_user_site
-    SPEC(warn_default_encoding, BOOL, READ_ONLY, NO_SYS, NO_GLOBAL),
+    SPEC(user_site_directory, BOOL, READ_ONLY, NO_SYS),  // 
sys.flags.no_user_site
+    SPEC(warn_default_encoding, BOOL, READ_ONLY, NO_SYS),
 
     // --- Init-only options -----------
 
-    SPEC(_config_init, UINT, INIT_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(_init_main, BOOL, INIT_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(_install_importlib, BOOL, INIT_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(_is_python_build, BOOL, INIT_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(module_search_paths_set, BOOL, INIT_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(pythonpath_env, WSTR_OPT, INIT_ONLY, NO_SYS, NO_GLOBAL),
-    SPEC(sys_path_0, WSTR_OPT, INIT_ONLY, NO_SYS, NO_GLOBAL),
+    SPEC(_config_init, UINT, INIT_ONLY, NO_SYS),
+    SPEC(_init_main, BOOL, INIT_ONLY, NO_SYS),
+    SPEC(_install_importlib, BOOL, INIT_ONLY, NO_SYS),
+    SPEC(_is_python_build, BOOL, INIT_ONLY, NO_SYS),
+    SPEC(module_search_paths_set, BOOL, INIT_ONLY, NO_SYS),
+    SPEC(pythonpath_env, WSTR_OPT, INIT_ONLY, NO_SYS),
+    SPEC(sys_path_0, WSTR_OPT, INIT_ONLY, NO_SYS),
 
     // Array terminator
     {NULL, 0, 0, 0, NO_SYS},
@@ -252,16 +239,11 @@ static const PyConfigSpec PYPRECONFIG_SPEC[] = {
     {NULL, 0, 0, 0, NO_SYS},
 };
 
-// End of ignoring deprecations on global variables
-_Py_COMP_DIAG_POP
-
 #undef SPEC
 #undef SYS_ATTR
 #undef SYS_FLAG_SETTER
 #undef SYS_FLAG
 #undef NO_SYS
-#undef GLOBAL
-#undef NO_GLOBAL
 
 
 // Forward declarations
@@ -611,45 +593,30 @@ static const char usage_envvars[] =
 
 /* --- Global configuration variables ----------------------------- */
 
+// Variable removed from Python limited C API 3.16, but kept in the stable ABI
+PyAPI_DATA(int) Py_UTF8Mode;
+
 /* UTF-8 mode (PEP 540): if equal to 1, use the UTF-8 encoding, and change
    stdin and stdout error handler to "surrogateescape". */
 int Py_UTF8Mode = 0;
-int Py_DebugFlag = 0; /* Needed by parser.c */
-int Py_VerboseFlag = 0; /* Needed by import.c */
-int Py_QuietFlag = 0; /* Needed by sysmodule.c */
-int Py_InteractiveFlag = 0; /* Previously, was used by Py_FdIsInteractive() */
-int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */
-int Py_OptimizeFlag = 0; /* Needed by compile.c */
-int Py_NoSiteFlag = 0; /* Suppress 'import site' */
-int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */
-int Py_FrozenFlag = 0; /* Needed by getpath.c */
-int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
-int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */
-int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
-int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
-int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
-int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
-#ifdef MS_WINDOWS
-int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
-int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO 
*/
-#endif
 
 
 static PyObject *
 _Py_GetGlobalVariablesAsDict(void)
 {
-_Py_COMP_DIAG_PUSH
-_Py_COMP_DIAG_IGNORE_DEPR_DECLS
-    PyObject *dict, *obj;
+    extern const char *Py_FileSystemDefaultEncoding;
+    extern const char *Py_FileSystemDefaultEncodeErrors;
+    extern int Py_HasFileSystemDefaultEncoding;
+    extern int _Py_HasFileSystemDefaultEncodeErrors;
 
-    dict = PyDict_New();
+    PyObject *dict = PyDict_New();
     if (dict == NULL) {
         return NULL;
     }
 
 #define SET_ITEM(KEY, EXPR) \
         do { \
-            obj = (EXPR); \
+            PyObject *obj = (EXPR); \
             if (obj == NULL) { \
                 goto fail; \
             } \
@@ -674,27 +641,6 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
     SET_ITEM_INT(_Py_HasFileSystemDefaultEncodeErrors);
 
     SET_ITEM_INT(Py_UTF8Mode);
-    SET_ITEM_INT(Py_DebugFlag);
-    SET_ITEM_INT(Py_VerboseFlag);
-    SET_ITEM_INT(Py_QuietFlag);
-    SET_ITEM_INT(Py_InteractiveFlag);
-    SET_ITEM_INT(Py_InspectFlag);
-
-    SET_ITEM_INT(Py_OptimizeFlag);
-    SET_ITEM_INT(Py_NoSiteFlag);
-    SET_ITEM_INT(Py_BytesWarningFlag);
-    SET_ITEM_INT(Py_FrozenFlag);
-    SET_ITEM_INT(Py_IgnoreEnvironmentFlag);
-    SET_ITEM_INT(Py_DontWriteBytecodeFlag);
-    SET_ITEM_INT(Py_NoUserSiteDirectory);
-    SET_ITEM_INT(Py_UnbufferedStdioFlag);
-    SET_ITEM_INT(Py_HashRandomizationFlag);
-    SET_ITEM_INT(Py_IsolatedFlag);
-
-#ifdef MS_WINDOWS
-    SET_ITEM_INT(Py_LegacyWindowsFSEncodingFlag);
-    SET_ITEM_INT(Py_LegacyWindowsStdioFlag);
-#endif
 
     return dict;
 
@@ -706,7 +652,6 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
 #undef SET_ITEM
 #undef SET_ITEM_INT
 #undef SET_ITEM_STR
-_Py_COMP_DIAG_POP
 }
 
 char*
@@ -1834,38 +1779,6 @@ config_read_preconfig(PyConfig *config)
 }
 
 
-/* Set Py_xxx global configuration variables from 'config' configuration. */
-static void
-config_set_global_vars(const PyConfig *config)
-{
-    const PyConfigSpec *spec = PYCONFIG_SPEC;
-    for (; spec->name != NULL; spec++) {
-        if (spec->global_var.ptr == NULL) {
-            continue;
-        }
-        assert(spec->type == PyConfig_MEMBER_INT
-               || spec->type == PyConfig_MEMBER_UINT
-               || spec->type == PyConfig_MEMBER_BOOL);
-        int *member = config_get_spec_member(config, spec);
-        int value = *member;
-        if (value == -1) {
-            continue;
-        }
-        if (spec->global_var.not) {
-            value = !value;
-        }
-        *spec->global_var.ptr = value;
-    }
-
-_Py_COMP_DIAG_PUSH
-_Py_COMP_DIAG_IGNORE_DEPR_DECLS
-    /* Random or non-zero hash seed */
-    Py_HashRandomizationFlag = (config->use_hash_seed == 0 ||
-                                config->hash_seed != 0);
-_Py_COMP_DIAG_POP
-}
-
-
 static const wchar_t*
 config_get_xoption(const PyConfig *config, wchar_t *name)
 {
@@ -3012,8 +2925,6 @@ config_init_stdio(const PyConfig *config)
 PyStatus
 _PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
 {
-    config_set_global_vars(config);
-
     if (config->configure_c_stdio) {
         config_init_stdio(config);
     }
@@ -5043,16 +4954,6 @@ PyConfig_Set(const char *name, PyObject *value)
         Py_UNREACHABLE();
     }
 
-    // Set the global variable
-    if (spec->global_var.ptr != NULL) {
-        assert(has_int_value);
-        int value = int_value;
-        if (spec->global_var.not) {
-            value = !value;
-        }
-        *spec->global_var.ptr = value;
-    }
-
     if (spec->sys.attr != NULL) {
         // Set the sys attribute, but don't set PyInterpreterState.config
         // to keep the code simple.
diff --git a/Python/preconfig.c b/Python/preconfig.c
index 16594e545abaedf..844ac8e6372fc52 100644
--- a/Python/preconfig.c
+++ b/Python/preconfig.c
@@ -13,10 +13,18 @@
 /* Forward declarations */
 static void
 preconfig_copy(PyPreConfig *config, const PyPreConfig *config2);
+extern int Py_UTF8Mode;
 
 
 /* --- File system encoding/errors -------------------------------- */
 
+// Variables removed from Python limited C API 3.16, but kept in the stable ABI
+PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
+PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors;
+PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding;
+
+// The default encoding used by the platform file system APIs.
+// If non-NULL, this is different than the default encoding for strings.
 const char *Py_FileSystemDefaultEncoding = NULL;
 int Py_HasFileSystemDefaultEncoding = 0;
 const char *Py_FileSystemDefaultEncodeErrors = NULL;
@@ -25,8 +33,6 @@ int _Py_HasFileSystemDefaultEncodeErrors = 0;
 void
 _Py_ClearFileSystemEncoding(void)
 {
-_Py_COMP_DIAG_PUSH
-_Py_COMP_DIAG_IGNORE_DEPR_DECLS
     if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
         PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
         Py_FileSystemDefaultEncoding = NULL;
@@ -35,7 +41,6 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
         PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors);
         Py_FileSystemDefaultEncodeErrors = NULL;
     }
-_Py_COMP_DIAG_POP
 }
 
 
@@ -60,14 +65,11 @@ _Py_SetFileSystemEncoding(const char *encoding, const char 
*errors)
 
     _Py_ClearFileSystemEncoding();
 
-_Py_COMP_DIAG_PUSH
-_Py_COMP_DIAG_IGNORE_DEPR_DECLS
     Py_FileSystemDefaultEncoding = encoding2;
     Py_HasFileSystemDefaultEncoding = 0;
 
     Py_FileSystemDefaultEncodeErrors = errors2;
     _Py_HasFileSystemDefaultEncodeErrors = 0;
-_Py_COMP_DIAG_POP
     return 0;
 }
 
@@ -470,39 +472,18 @@ preconfig_get_global_var(PyPreConfig *config)
         return;
     }
 
-_Py_COMP_DIAG_PUSH
-_Py_COMP_DIAG_IGNORE_DEPR_DECLS
     if (Py_UTF8Mode > 0) {
         config->utf8_mode = Py_UTF8Mode;
     }
-_Py_COMP_DIAG_POP
 }
 
 
 static void
-preconfig_set_global_vars(const PyPreConfig *config)
+preconfig_set_global_var(const PyPreConfig *config)
 {
-#define COPY_FLAG(ATTR, VAR) \
-    if (config->ATTR >= 0) { \
-        VAR = config->ATTR; \
-    }
-#define COPY_NOT_FLAG(ATTR, VAR) \
-    if (config->ATTR >= 0) { \
-        VAR = !config->ATTR; \
+    if (config->utf8_mode >= 0) {
+        Py_UTF8Mode = config->utf8_mode;
     }
-
-_Py_COMP_DIAG_PUSH
-_Py_COMP_DIAG_IGNORE_DEPR_DECLS
-    COPY_FLAG(isolated, Py_IsolatedFlag);
-    COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
-#ifdef MS_WINDOWS
-    COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag);
-#endif
-    COPY_FLAG(utf8_mode, Py_UTF8Mode);
-_Py_COMP_DIAG_POP
-
-#undef COPY_FLAG
-#undef COPY_NOT_FLAG
 }
 
 
@@ -935,7 +916,7 @@ _PyPreConfig_Write(const PyPreConfig *src_config)
         }
     }
 
-    preconfig_set_global_vars(&config);
+    preconfig_set_global_var(&config);
 
     if (config.configure_locale) {
         if (config.coerce_c_locale) {
diff --git a/Tools/c-analyzer/cpython/ignored.tsv 
b/Tools/c-analyzer/cpython/ignored.tsv
index 60ff561776b76dd..2ad801c671855cf 100644
--- a/Tools/c-analyzer/cpython/ignored.tsv
+++ b/Tools/c-analyzer/cpython/ignored.tsv
@@ -778,6 +778,7 @@ Modules/expat/xmlrole.c     -       condSect1       -
 Modules/expat/xmlrole.c        -       condSect2       -
 Modules/expat/xmlrole.c        -       declClose       -
 Modules/expat/xmlrole.c        -       error   -
+Python/preconfig.c     -       Py_UTF8Mode     -
 
 ## other
 Modules/_io/_iomodule.c        -       _PyIO_Module    -

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to