[Python-checkins] bpo-36763: Implement the PEP 587 (GH-13592)

Victor Stinner webhook-mailer at python.org
Mon May 27 10:39:29 EDT 2019


https://github.com/python/cpython/commit/331a6a56e9a9c72f3e4605987fabdaec72677702
commit: 331a6a56e9a9c72f3e4605987fabdaec72677702
branch: master
author: Victor Stinner <vstinner at redhat.com>
committer: GitHub <noreply at github.com>
date: 2019-05-27T16:39:22+02:00
summary:

bpo-36763: Implement the PEP 587 (GH-13592)

* Add a whole new documentation page:
  "Python Initialization Configuration"
* PyWideStringList_Append() return type is now PyStatus,
  instead of int
* PyInterpreterState_New() now calls PyConfig_Clear() if
  PyConfig_InitPythonConfig() fails.
* Rename files:

  * Python/coreconfig.c => Python/initconfig.c
  * Include/cpython/coreconfig.h => Include/cpython/initconfig.h
  * Include/internal/: pycore_coreconfig.h => pycore_initconfig.h

* Rename structures

  * _PyCoreConfig => PyConfig
  * _PyPreConfig => PyPreConfig
  * _PyInitError => PyStatus
  * _PyWstrList => PyWideStringList

* Rename PyConfig fields:

  * use_module_search_paths => module_search_paths_set
  * module_search_path_env => pythonpath_env

* Rename PyStatus field: _func => func
* PyInterpreterState: rename core_config field to config
* Rename macros and functions:

  * _PyCoreConfig_SetArgv() => PyConfig_SetBytesArgv()
  * _PyCoreConfig_SetWideArgv() => PyConfig_SetArgv()
  * _PyCoreConfig_DecodeLocale() => PyConfig_SetBytesString()
  * _PyInitError_Failed() => PyStatus_Exception()
  * _Py_INIT_ERROR_TYPE_xxx enums => _PyStatus_TYPE_xxx
  * _Py_UnixMain() => Py_BytesMain()
  * _Py_ExitInitError() => Py_ExitStatusException()
  * _Py_PreInitializeFromArgs() => Py_PreInitializeFromBytesArgs()
  * _Py_PreInitializeFromWideArgs() => Py_PreInitializeFromArgs()
  * _Py_PreInitialize() => Py_PreInitialize()
  * _Py_RunMain() => Py_RunMain()
  * _Py_InitializeFromConfig() => Py_InitializeFromConfig()
  * _Py_INIT_XXX() => _PyStatus_XXX()
  * _Py_INIT_FAILED() => _PyStatus_EXCEPTION()

* Rename 'err' PyStatus variables to 'status'
* Convert RUN_CODE() macro to config_run_code() static inline function
* Remove functions:

  * _Py_InitializeFromArgs()
  * _Py_InitializeFromWideArgs()
  * _PyInterpreterState_GetCoreConfig()

files:
A Doc/c-api/init_config.rst
A Include/cpython/initconfig.h
A Include/internal/pycore_initconfig.h
A Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst
A Python/initconfig.c
D Include/cpython/coreconfig.h
D Include/internal/pycore_coreconfig.h
D Python/coreconfig.c
M Doc/c-api/index.rst
M Doc/c-api/veryhigh.rst
M Doc/whatsnew/3.8.rst
M Include/Python.h
M Include/cpython/pylifecycle.h
M Include/cpython/pystate.h
M Include/internal/pycore_pathconfig.h
M Include/internal/pycore_pylifecycle.h
M Include/internal/pycore_pystate.h
M Lib/test/test_embed.py
M Makefile.pre.in
M Modules/_io/_iomodule.c
M Modules/_io/iobase.c
M Modules/_testinternalcapi.c
M Modules/faulthandler.c
M Modules/getpath.c
M Modules/main.c
M Objects/bytearrayobject.c
M Objects/bytesobject.c
M Objects/exceptions.c
M Objects/listobject.c
M Objects/moduleobject.c
M Objects/object.c
M Objects/tupleobject.c
M Objects/unicodeobject.c
M PC/getpathp.c
M PCbuild/pythoncore.vcxproj
M PCbuild/pythoncore.vcxproj.filters
M Programs/_freeze_importlib.c
M Programs/_testembed.c
M Programs/python.c
M Python/bltinmodule.c
M Python/bootstrap_hash.c
M Python/compile.c
M Python/dynload_hpux.c
M Python/errors.c
M Python/frozenmain.c
M Python/import.c
M Python/pathconfig.c
M Python/preconfig.c
M Python/pylifecycle.c
M Python/pystate.c
M Python/pythonrun.c
M Python/sysmodule.c

diff --git a/Doc/c-api/index.rst b/Doc/c-api/index.rst
index 3bfbaf4eedde..9a8f1507b3f4 100644
--- a/Doc/c-api/index.rst
+++ b/Doc/c-api/index.rst
@@ -21,6 +21,7 @@ document the API functions in detail.
    abstract.rst
    concrete.rst
    init.rst
+   init_config.rst
    memory.rst
    objimpl.rst
    apiabiversion.rst
diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst
new file mode 100644
index 000000000000..0d94e6b8f27b
--- /dev/null
+++ b/Doc/c-api/init_config.rst
@@ -0,0 +1,1018 @@
+.. highlight:: c
+
+.. _init-config:
+
+***********************************
+Python Initialization Configuration
+***********************************
+
+.. versionadded:: 3.8
+
+Structures:
+
+* :c:type:`PyConfig`
+* :c:type:`PyPreConfig`
+* :c:type:`PyStatus`
+* :c:type:`PyWideStringList`
+
+Functions:
+
+* :c:func:`PyConfig_Clear`
+* :c:func:`PyConfig_InitIsolatedConfig`
+* :c:func:`PyConfig_InitPythonConfig`
+* :c:func:`PyConfig_Read`
+* :c:func:`PyConfig_SetArgv`
+* :c:func:`PyConfig_SetBytesArgv`
+* :c:func:`PyConfig_SetBytesString`
+* :c:func:`PyConfig_SetString`
+* :c:func:`PyPreConfig_InitIsolatedConfig`
+* :c:func:`PyPreConfig_InitPythonConfig`
+* :c:func:`PyStatus_Error`
+* :c:func:`PyStatus_Exception`
+* :c:func:`PyStatus_Exit`
+* :c:func:`PyStatus_IsError`
+* :c:func:`PyStatus_IsExit`
+* :c:func:`PyStatus_NoMemory`
+* :c:func:`PyStatus_Ok`
+* :c:func:`PyWideStringList_Append`
+* :c:func:`PyWideStringList_Insert`
+* :c:func:`Py_ExitStatusException`
+* :c:func:`Py_InitializeFromConfig`
+* :c:func:`Py_PreInitialize`
+* :c:func:`Py_PreInitializeFromArgs`
+* :c:func:`Py_PreInitializeFromBytesArgs`
+* :c:func:`Py_RunMain`
+
+The preconfiguration (``PyPreConfig`` type) is stored in
+``_PyRuntime.preconfig`` and the configuration (``PyConfig`` type) is stored in
+``PyInterpreterState.config``.
+
+.. seealso::
+   :pep:`587` "Python Initialization Configuration".
+
+
+PyWideStringList
+----------------
+
+.. c:type:: PyWideStringList
+
+   List of ``wchar_t*`` strings.
+
+   If *length* is non-zero, *items* must be non-NULL and all strings must be
+   non-NULL.
+
+   Methods:
+
+   .. c:function:: PyStatus PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
+
+      Append *item* to *list*.
+
+      Python must be preinitialized to call this function.
+
+   .. c:function:: PyStatus PyWideStringList_Insert(PyWideStringList *list, Py_ssize_t index, const wchar_t *item)
+
+      Insert *item* into *list* at *index*. If *index* is greater than *list*
+      length, just append *item* to *list*.
+
+      Python must be preinitialized to call this function.
+
+   Structure fields:
+
+   .. c:member:: Py_ssize_t length
+
+      List length.
+
+   .. c:member:: wchar_t** items
+
+      List items.
+
+PyStatus
+--------
+
+.. c:type:: PyStatus
+
+   Structure to store an initialization function status: success, error
+   or exit.
+
+   For an error, it can store the C function name which created the error.
+
+   Structure fields:
+
+   .. c:member:: int exitcode
+
+      Exit code. Argument passed to ``exit()``.
+
+   .. c:member:: const char *err_msg
+
+      Error message.
+
+   .. c:member:: const char *func
+
+      Name of the function which created an error, can be ``NULL``.
+
+   Functions to create a status:
+
+   .. c:function:: PyStatus PyStatus_Ok(void)
+
+      Success.
+
+   .. c:function:: PyStatus PyStatus_Error(const char *err_msg)
+
+      Initialization error with a message.
+
+   .. c:function:: PyStatus PyStatus_NoMemory(void)
+
+      Memory allocation failure (out of memory).
+
+   .. c:function:: PyStatus PyStatus_Exit(int exitcode)
+
+      Exit Python with the specified exit code.
+
+   Functions to handle a status:
+
+   .. c:function:: int PyStatus_Exception(PyStatus status)
+
+      Is the status an error or an exit? If true, the exception must be
+      handled; by calling :c:func:`Py_ExitStatusException` for example.
+
+   .. c:function:: int PyStatus_IsError(PyStatus status)
+
+      Is the result an error?
+
+   .. c:function:: int PyStatus_IsExit(PyStatus status)
+
+      Is the result an exit?
+
+   .. c:function:: void Py_ExitStatusException(PyStatus status)
+
+      Call ``exit(exitcode)`` if *status* is an exit. Print the error
+      message and exit with a non-zero exit code if *status* is an error.  Must
+      only be called if ``PyStatus_Exception(status)`` is non-zero.
+
+.. note::
+   Internally, Python uses macros which set ``PyStatus.func``,
+   whereas functions to create a status set ``func`` to ``NULL``.
+
+Example::
+
+    PyStatus alloc(void **ptr, size_t size)
+    {
+        *ptr = PyMem_RawMalloc(size);
+        if (*ptr == NULL) {
+            return PyStatus_NoMemory();
+        }
+        return PyStatus_Ok();
+    }
+
+    int main(int argc, char **argv)
+    {
+        void *ptr;
+        PyStatus status = alloc(&ptr, 16);
+        if (PyStatus_Exception(status)) {
+            Py_ExitStatusException(status);
+        }
+        PyMem_Free(ptr);
+        return 0;
+    }
+
+
+PyPreConfig
+-----------
+
+.. c:type:: PyPreConfig
+
+   Structure used to preinitialize Python:
+
+   * Set the Python memory allocator
+   * Configure the LC_CTYPE locale
+   * Set the UTF-8 mode
+
+   Function to initialize a preconfiguration:
+
+   .. c:function:: void PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig)
+
+      Initialize the preconfiguration with :ref:`Python Configuration
+      <init-python-config>`.
+
+   .. c:function:: void PyPreConfig_InitPythonConfig(PyPreConfig *preconfig)
+
+      Initialize the preconfiguration with :ref:`Isolated Configuration
+      <init-isolated-conf>`.
+
+   Structure fields:
+
+   .. c:member:: int allocator
+
+      Name of the memory allocator:
+
+      * ``PYMEM_ALLOCATOR_NOT_SET`` (``0``): don't change memory allocators
+        (use defaults)
+      * ``PYMEM_ALLOCATOR_DEFAULT`` (``1``): default memory allocators
+      * ``PYMEM_ALLOCATOR_DEBUG`` (``2``): default memory allocators with
+        debug hooks
+      * ``PYMEM_ALLOCATOR_MALLOC`` (``3``): force usage of ``malloc()``
+      * ``PYMEM_ALLOCATOR_MALLOC_DEBUG`` (``4``): force usage of
+        ``malloc()`` with debug hooks
+      * ``PYMEM_ALLOCATOR_PYMALLOC`` (``5``): :ref:`Python pymalloc memory
+        allocator <pymalloc>`
+      * ``PYMEM_ALLOCATOR_PYMALLOC_DEBUG`` (``6``): :ref:`Python pymalloc
+        memory allocator <pymalloc>` with debug hooks
+
+      ``PYMEM_ALLOCATOR_PYMALLOC`` and ``PYMEM_ALLOCATOR_PYMALLOC_DEBUG``
+      are not supported if Python is configured using ``--without-pymalloc``
+
+      See :ref:`Memory Management <memory>`.
+
+   .. c:member:: int configure_locale
+
+      Set the LC_CTYPE locale to the user preferred locale? If equals to 0, set
+      :c:member:`coerce_c_locale` and :c:member:`coerce_c_locale_warn` to 0.
+
+   .. c:member:: int coerce_c_locale
+
+      If equals to 2, coerce the C locale; if equals to 1, read the LC_CTYPE
+      locale to decide if it should be coerced.
+
+   .. c:member:: int coerce_c_locale_warn
+      If non-zero, emit a warning if the C locale is coerced.
+
+   .. c:member:: int dev_mode
+
+      See :c:member:`PyConfig.dev_mode`.
+
+   .. c:member:: int isolated
+
+      See :c:member:`PyConfig.isolated`.
+
+   .. c:member:: int legacy_windows_fs_encoding (Windows only)
+
+      If non-zero, disable UTF-8 Mode, set the Python filesystem encoding to
+      ``mbcs``, set the filesystem error handler to ``replace``.
+
+      Only available on Windows. ``#ifdef MS_WINDOWS`` macro can be used for
+      Windows specific code.
+
+   .. c:member:: int parse_argv
+
+      If non-zero, :c:func:`Py_PreInitializeFromArgs` and
+      :c:func:`Py_PreInitializeFromBytesArgs` parse their ``argv`` argument the
+      same way the regular Python parses command line arguments: see
+      :ref:`Command Line Arguments <using-on-cmdline>`.
+
+   .. c:member:: int use_environment
+
+      See :c:member:`PyConfig.use_environment`.
+
+   .. c:member:: int utf8_mode
+
+      If non-zero, enable the UTF-8 mode.
+
+Preinitialization with PyPreConfig
+----------------------------------
+
+Functions to preinitialize Python:
+
+.. c:function:: PyStatus Py_PreInitialize(const PyPreConfig *preconfig)
+
+   Preinitialize Python from *preconfig* preconfiguration.
+
+.. c:function:: PyStatus Py_PreInitializeFromBytesArgs(const PyPreConfig *preconfig, int argc, char * const *argv)
+
+   Preinitialize Python from *preconfig* preconfiguration and command line
+   arguments (bytes strings).
+
+.. c:function:: PyStatus Py_PreInitializeFromArgs(const PyPreConfig *preconfig, int argc, wchar_t * const * argv)
+
+   Preinitialize Python from *preconfig* preconfiguration and command line
+   arguments (wide strings).
+
+The caller is responsible to handle exceptions (error or exit) using
+:c:func:`PyStatus_Exception` and :c:func:`Py_ExitStatusException`.
+
+For :ref:`Python Configuration <init-python-config>`
+(:c:func:`PyPreConfig_InitPythonConfig`), if Python is initialized with
+command line arguments, the command line arguments must also be passed to
+preinitialize Python, since they have an effect on the pre-configuration
+like encodings. For example, the :option:`-X` ``utf8`` command line option
+enables the UTF-8 Mode.
+
+``PyMem_SetAllocator()`` can be called after :c:func:`Py_PreInitialize` and
+before :c:func:`Py_InitializeFromConfig` to install a custom memory allocator.
+It can be called before :c:func:`Py_PreInitialize` if
+:c:member:`PyPreConfig.allocator` is set to ``PYMEM_ALLOCATOR_NOT_SET``.
+
+Python memory allocation functions like :c:func:`PyMem_RawMalloc` must not be
+used before Python preinitialization, whereas calling directly ``malloc()`` and
+``free()`` is always safe. :c:func:`Py_DecodeLocale` must not be called before
+the preinitialization.
+
+Example using the preinitialization to enable the UTF-8 Mode::
+
+    PyPreConfig preconfig;
+    PyPreConfig_InitPythonConfig(&preconfig);
+
+    preconfig.utf8_mode = 1;
+
+    PyStatus status = Py_PreInitialize(&preconfig);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
+    }
+
+    /* at this point, Python will speak UTF-8 */
+
+    Py_Initialize();
+    /* ... use Python API here ... */
+    Py_Finalize();
+
+
+PyConfig
+--------
+
+.. c:type:: PyConfig
+
+   Structure containing most parameters to configure Python.
+
+   Structure methods:
+
+   .. c:function:: PyStatus PyConfig_InitPythonConfig(PyConfig *config)
+
+      Initialize configuration with :ref:`Python Configuration
+      <init-python-config>`.
+
+   .. c:function:: PyStatus PyConfig_InitIsolatedConfig(PyConfig *config)
+
+      Initialize configuration with :ref:`Isolated Configuration
+      <init-isolated-conf>`.
+
+   .. c:function:: PyStatus PyConfig_SetString(PyConfig *config, wchar_t * const *config_str, const wchar_t *str)
+
+      Copy the wide character string *str* into ``*config_str``.
+
+      Preinitialize Python if needed.
+
+   .. c:function:: PyStatus PyConfig_SetBytesString(PyConfig *config, wchar_t * const *config_str, const char *str)
+
+      Decode *str* using ``Py_DecodeLocale()`` and set the result into ``*config_str``.
+
+      Preinitialize Python if needed.
+
+   .. c:function:: PyStatus PyConfig_SetArgv(PyConfig *config, int argc, wchar_t * const *argv)
+
+      Set command line arguments from wide character strings.
+
+      Preinitialize Python if needed.
+
+   .. c:function:: PyStatus PyConfig_SetBytesArgv(PyConfig *config, int argc, char * const *argv)
+
+      Set command line arguments: decode bytes using :c:func:`Py_DecodeLocale`.
+
+      Preinitialize Python if needed.
+
+   .. c:function:: PyStatus PyConfig_Read(PyConfig *config)
+
+      Read all Python configuration.
+
+      Fields which are already initialized are left unchanged.
+
+      Preinitialize Python if needed.
+
+   .. c:function:: void PyConfig_Clear(PyConfig *config)
+
+      Release configuration memory.
+
+   Most ``PyConfig`` methods preinitialize Python if needed. In that case, the
+   Python preinitialization configuration in based on the :c:type:`PyConfig`.
+   If configuration fields which are in common with :c:type:`PyPreConfig` are
+   tuned, they must be set before calling a :c:type:`PyConfig` method:
+
+   * :c:member:`~PyConfig.dev_mode`
+   * :c:member:`~PyConfig.isolated`
+   * :c:member:`~PyConfig.parse_argv`
+   * :c:member:`~PyConfig.use_environment`
+
+   Moreover, if :c:func:`PyConfig_SetArgv` or :c:func:`PyConfig_SetBytesArgv`
+   is used, this method must be called first, before other methods, since the
+   preinitialization configuration depends on command line arguments (if
+   :c:member:`parse_argv` is non-zero).
+
+   The caller of these methods is responsible to handle exceptions (error or
+   exit) using ``PyStatus_Exception()`` and ``Py_ExitStatusException()``.
+
+   Structure fields:
+
+   .. c:member:: PyWideStringList argv
+
+      Command line arguments, :data:`sys.argv`. See
+      :c:member:`~PyConfig.parse_argv` to parse :c:member:`~PyConfig.argv` the
+      same way the regular Python parses Python command line arguments. If
+      :c:member:`~PyConfig.argv` is empty, an empty string is added to ensure
+      that :data:`sys.argv` always exists and is never empty.
+
+   .. c:member:: wchar_t* base_exec_prefix
+
+      :data:`sys.base_exec_prefix`.
+
+   .. c:member:: wchar_t* base_prefix
+
+      :data:`sys.base_prefix`.
+
+   .. c:member:: int buffered_stdio
+
+      If equals to 0, enable unbuffered mode, making the stdout and stderr
+      streams unbuffered.
+
+      stdin is always opened in buffered mode.
+
+   .. c:member:: int bytes_warning
+
+      If equals to 1, issue a warning when comparing :class:`bytes` or
+      :class:`bytearray` with :class:`str`, or comparing :class:`bytes` with
+      :class:`int`. If equal or greater to 2, raise a :exc:`BytesWarning`
+      exception.
+
+   .. c:member:: wchar_t* check_hash_pycs_mode
+
+      Control the validation behavior of hash-based ``.pyc`` files (see
+      :pep:`552`): :option:`--check-hash-based-pycs` command line option value.
+
+      Valid values: ``always``, ``never`` and ``default``.
+
+      The default value is: ``default``.
+
+   .. c:member:: int configure_c_stdio
+
+      If non-zero, configure C standard streams (``stdio``, ``stdout``,
+      ``stdout``). For example, set their mode to ``O_BINARY`` on Windows.
+
+   .. c:member:: int dev_mode
+
+      Development mode: see :option:`-X` ``dev``.
+
+   .. c:member:: int dump_refs
+
+      If non-zero, dump all objects which are still alive at exit.
+
+      Require a debug build of Python (``Py_REF_DEBUG`` macro must be defined).
+
+   .. c:member:: wchar_t* exec_prefix
+
+      :data:`sys.exec_prefix`.
+
+   .. c:member:: wchar_t* executable
+
+      :data:`sys.executable`.
+
+   .. c:member:: int faulthandler
+
+      If non-zero, call :func:`faulthandler.enable`.
+
+   .. c:member:: wchar_t* filesystem_encoding
+
+      Filesystem encoding, :func:`sys.getfilesystemencoding`.
+
+   .. c:member:: wchar_t* filesystem_errors
+
+      Filesystem encoding errors, :func:`sys.getfilesystemencodeerrors`.
+
+   .. c:member:: unsigned long hash_seed
+   .. c:member:: int use_hash_seed
+
+      Randomized hash function seed.
+
+      If :c:member:`~PyConfig.use_hash_seed` is zero, a seed is chosen randomly
+      at Pythonstartup, and :c:member:`~PyConfig.hash_seed` is ignored.
+
+   .. c:member:: wchar_t* home
+
+      Python home directory.
+
+   .. c:member:: int import_time
+
+      If non-zero, profile import time.
+
+   .. c:member:: int inspect
+
+      Enter interactive mode after executing a script or a command.
+
+   .. c:member:: int install_signal_handlers
+
+      Install signal handlers?
+
+   .. c:member:: int interactive
+
+      Interactive mode.
+
+   .. c:member:: int isolated
+
+      If greater than 0, enable isolated mode:
+
+      * :data:`sys.path` contains neither the script's directory (computed from
+        ``argv[0]`` or the current directory) nor the user's site-packages
+        directory.
+      * Python REPL doesn't import :mod:`readline` nor enable default readline
+        configuration on interactive prompts.
+      * Set :c:member:`~PyConfig.use_environment` and
+        :c:member:`~PyConfig.user_site_directory` to 0.
+
+   .. c:member:: int legacy_windows_stdio
+
+      If non-zero, use :class:`io.FileIO` instead of
+      :class:`io.WindowsConsoleIO` for :data:`sys.stdin`, :data:`sys.stdout`
+      and :data:`sys.stderr`.
+
+      Only available on Windows. ``#ifdef MS_WINDOWS`` macro can be used for
+      Windows specific code.
+
+   .. c:member:: int malloc_stats
+
+      If non-zero, dump statistics on :ref:`Python pymalloc memory allocator
+      <pymalloc>` at exit.
+
+      The option is ignored if Python is built using ``--without-pymalloc``.
+
+   .. c:member:: wchar_t* pythonpath_env
+
+      Module search paths as a string separated by ``DELIM``
+      (:data:`os.path.pathsep`).
+
+      Initialized from :envvar:`PYTHONPATH` environment variable value by
+      default.
+
+   .. c:member:: PyWideStringList module_search_paths
+   .. c:member:: int module_search_paths_set
+
+      :data:`sys.path`. If :c:member:`~PyConfig.module_search_paths_set` is
+      equal to 0, the :c:member:`~PyConfig.module_search_paths` is overridden
+      by the function computing the :ref:`Path Configuration
+      <init-path-config>`.
+
+   .. c:member:: int optimization_level
+
+      Compilation optimization level:
+
+      * 0: Peephole optimizer (and ``__debug__`` is set to ``True``)
+      * 1: Remove assertions, set ``__debug__`` to ``False``
+      * 2: Strip docstrings
+
+   .. c:member:: int parse_argv
+
+      If non-zero, parse :c:member:`~PyConfig.argv` the same way the regular
+      Python command line arguments, and strip Python arguments from
+      :c:member:`~PyConfig.argv`: see :ref:`Command Line Arguments
+      <using-on-cmdline>`.
+
+   .. c:member:: int parser_debug
+
+      If non-zero, turn on parser debugging output (for expert only, depending
+      on compilation options).
+
+   .. c:member:: int pathconfig_warnings
+
+      If equal to 0, suppress warnings when computing the path configuration
+      (Unix only, Windows does not log any warning). Otherwise, warnings are
+      written into ``stderr``.
+
+   .. c:member:: wchar_t* prefix
+
+      :data:`sys.prefix`.
+
+   .. c:member:: wchar_t* program_name
+
+      Program name.
+
+   .. c:member:: wchar_t* pycache_prefix
+
+      ``.pyc`` cache prefix.
+
+   .. c:member:: int quiet
+
+      Quiet mode. For example, don't display the copyright and version messages
+      even in interactive mode.
+
+   .. c:member:: wchar_t* run_command
+
+      ``python3 -c COMMAND`` argument.
+
+   .. c:member:: wchar_t* run_filename
+
+      ``python3 FILENAME`` argument.
+
+   .. c:member:: wchar_t* run_module
+
+      ``python3 -m MODULE`` argument.
+
+   .. c:member:: int show_alloc_count
+
+      Show allocation counts at exit?
+
+      Need a special Python build with ``COUNT_ALLOCS`` macro defined.
+
+   .. c:member:: int show_ref_count
+
+      Show total reference count at exit?
+
+      Need a debug build of Python (``Py_REF_DEBUG`` macro must be defined).
+
+   .. c:member:: int site_import
+
+      Import the :mod:`site` module at startup?
+
+   .. c:member:: int skip_source_first_line
+
+      Skip the first line of the source?
+
+   .. c:member:: wchar_t* stdio_encoding
+   .. c:member:: wchar_t* stdio_errors
+
+      Encoding and encoding errors of :data:`sys.stdin`, :data:`sys.stdout` and
+      :data:`sys.stderr`.
+
+   .. c:member:: int tracemalloc
+
+      If non-zero, call :func:`tracemalloc.start`.
+
+   .. c:member:: int use_environment
+
+      If greater than 0, use :ref:`environment variables <using-on-envvars>`.
+
+   .. c:member:: int user_site_directory
+
+      If non-zero, add user site directory to :data:`sys.path`.
+
+   .. c:member:: int verbose
+
+      If non-zero, enable verbose mode.
+
+   .. c:member:: PyWideStringList warnoptions
+
+      Options of the :mod:`warnings` module to build warnings filters.
+
+   .. c:member:: int write_bytecode
+
+      If non-zero, write ``.pyc`` files.
+
+   .. c:member:: PyWideStringList xoptions
+
+      :data:`sys._xoptions`.
+
+If ``parse_argv`` is non-zero, ``argv`` arguments are parsed the same
+way the regular Python parses command line arguments, and Python
+arguments are stripped from ``argv``: see :ref:`Command Line Arguments
+<using-on-cmdline>`.
+
+The ``xoptions`` options are parsed to set other options: see :option:`-X`
+option.
+
+
+Initialization with PyConfig
+----------------------------
+
+Function to initialize Python:
+
+.. c:function:: PyStatus Py_InitializeFromConfig(const PyConfig *config)
+
+   Initialize Python from *config* configuration.
+
+The caller is responsible to handle exceptions (error or exit) using
+:c:func:`PyStatus_Exception` and :c:func:`Py_ExitStatusException`.
+
+``PyImport_FrozenModules``, ``PyImport_AppendInittab()`` or
+``PyImport_ExtendInittab()`` is used: they must be set or called after Python
+preinitialization and before the Python initialization.
+
+Example setting the program name::
+
+    void init_python(void)
+    {
+        PyStatus status;
+        PyConfig config;
+
+        status = PyConfig_InitPythonConfig(&config);
+        if (PyStatus_Exception(status)) {
+            goto fail;
+        }
+
+        /* Set the program name. Implicitly preinitialize Python. */
+        status = PyConfig_SetString(&config, &config.program_name,
+                                    L"/path/to/my_program");
+        if (PyStatus_Exception(status)) {
+            goto fail;
+        }
+
+        status = Py_InitializeFromConfig(&config);
+        if (PyStatus_Exception(status)) {
+            goto fail;
+        }
+        PyConfig_Clear(&config);
+        return;
+
+    fail:
+        PyConfig_Clear(&config);
+        Py_ExitStatusException(status);
+    }
+
+More complete example modifying the default configuration, read the
+configuration, and then override some parameters::
+
+    PyStatus init_python(const char *program_name)
+    {
+        PyStatus status;
+        PyConfig config;
+
+        status = PyConfig_InitPythonConfig(&config);
+        if (PyStatus_Exception(status)) {
+            goto done;
+        }
+
+        /* Set the program name before reading the configuraton
+           (decode byte string from the locale encoding).
+
+           Implicitly preinitialize Python. */
+        status = PyConfig_SetBytesString(&config, &config.program_name,
+                                      program_name);
+        if (PyStatus_Exception(status)) {
+            goto done;
+        }
+
+        /* Read all configuration at once */
+        status = PyConfig_Read(&config);
+        if (PyStatus_Exception(status)) {
+            goto done;
+        }
+
+        /* Append our custom search path to sys.path */
+        status = PyWideStringList_Append(&config.module_search_paths,
+                                      L"/path/to/more/modules");
+        if (PyStatus_Exception(status)) {
+            goto done;
+        }
+
+        /* Override executable computed by PyConfig_Read() */
+        status = PyConfig_SetString(&config, &config.executable,
+                                    L"/path/to/my_executable");
+        if (PyStatus_Exception(status)) {
+            goto done;
+        }
+
+        status = Py_InitializeFromConfig(&config);
+
+    done:
+        PyConfig_Clear(&config);
+        return status;
+    }
+
+
+.. _init-isolated-conf:
+
+Isolated Configuration
+----------------------
+
+:c:func:`PyPreConfig_InitIsolatedConfig` and
+:c:func:`PyConfig_InitIsolatedConfig` functions create a configuration to
+isolate Python from the system. For example, to embed Python into an
+application.
+
+This configuration ignores global configuration variables, environments
+variables and command line arguments (:c:member:`PyConfig.argv` is not parsed).
+The C standard streams (ex: ``stdout``) and the LC_CTYPE locale are left
+unchanged by default.
+
+Configuration files are still used with this configuration. Set the
+:ref:`Path Configuration <init-path-config>` ("output fields") to ignore these
+configuration files and avoid the function computing the default path
+configuration.
+
+
+.. _init-python-config:
+
+Python Configuration
+--------------------
+
+:c:func:`PyPreConfig_InitPythonConfig` and :c:func:`PyConfig_InitPythonConfig`
+functions create a configuration to build a customized Python which behaves as
+the regular Python.
+
+Environments variables and command line arguments are used to configure
+Python, whereas global configuration variables are ignored.
+
+This function enables C locale coercion (:pep:`538`) and UTF-8 Mode
+(:pep:`540`) depending on the LC_CTYPE locale, :envvar:`PYTHONUTF8` and
+:envvar:`PYTHONCOERCECLOCALE` environment variables.
+
+Example of customized Python always running in isolated mode::
+
+    int main(int argc, char **argv)
+    {
+        PyConfig config;
+        PyStatus status;
+
+        status = PyConfig_InitPythonConfig(&config);
+        if (PyStatus_Exception(status)) {
+            goto fail;
+        }
+
+        config.isolated = 1;
+
+        /* Decode command line arguments.
+           Implicitly preinitialize Python (in isolated mode). */
+        status = PyConfig_SetBytesArgv(&config, argc, argv);
+        if (PyStatus_Exception(status)) {
+            goto fail;
+        }
+
+        status = Py_InitializeFromConfig(&config);
+        if (PyStatus_Exception(status)) {
+            goto fail;
+        }
+        PyConfig_Clear(&config);
+
+        return Py_RunMain();
+
+    fail:
+        PyConfig_Clear(&config);
+        if (PyStatus_IsExit(status)) {
+            return status.exitcode;
+        }
+        /* Display the error message and exit the process with
+           non-zero exit code */
+        Py_ExitStatusException(status);
+    }
+
+
+.. _init-path-config:
+
+Path Configuration
+------------------
+
+:c:type:`PyConfig` contains multiple fields for the path configuration:
+
+* Path configuration input fields:
+
+  * :c:member:`PyConfig.home`
+  * :c:member:`PyConfig.pythonpath_env`
+  * :c:member:`PyConfig.pathconfig_warnings`
+
+* Path configuration output fields:
+
+  * :c:member:`PyConfig.exec_prefix`
+  * :c:member:`PyConfig.executable`
+  * :c:member:`PyConfig.prefix`
+  * :c:member:`PyConfig.module_search_paths_set`,
+    :c:member:`PyConfig.module_search_paths`
+
+If at least one "output field" is not set, Python computes the path
+configuration to fill unset fields. If
+:c:member:`~PyConfig.module_search_paths_set` is equal to 0,
+:c:member:`~PyConfig.module_search_paths` is overriden and
+:c:member:`~PyConfig.module_search_paths_set` is set to 1.
+
+It is possible to completely ignore the function computing the default
+path configuration by setting explicitly all path configuration output
+fields listed above. A string is considered as set even if it is non-empty.
+``module_search_paths`` is considered as set if
+``module_search_paths_set`` is set to 1. In this case, path
+configuration input fields are ignored as well.
+
+Set :c:member:`~PyConfig.pathconfig_warnings` to 0 to suppress warnings when
+computing the path configuration (Unix only, Windows does not log any warning).
+
+If :c:member:`~PyConfig.base_prefix` or :c:member:`~PyConfig.base_exec_prefix`
+fields are not set, they inherit their value from :c:member:`~PyConfig.prefix`
+and :c:member:`~PyConfig.exec_prefix` respectively.
+
+:c:func:`Py_RunMain` and :c:func:`Py_Main` modify :data:`sys.path`:
+
+* If :c:member:`~PyConfig.run_filename` is set and is a directory which contains a
+  ``__main__.py`` script, prepend :c:member:`~PyConfig.run_filename` to
+  :data:`sys.path`.
+* If :c:member:`~PyConfig.isolated` is zero:
+
+  * If :c:member:`~PyConfig.run_module` is set, prepend the current directory
+    to :data:`sys.path`. Do nothing if the current directory cannot be read.
+  * If :c:member:`~PyConfig.run_filename` is set, prepend the directory of the
+    filename to :data:`sys.path`.
+  * Otherwise, prepend an empty string to :data:`sys.path`.
+
+If :c:member:`~PyConfig.site_import` is non-zero, :data:`sys.path` can be
+modified by the :mod:`site` module. If
+:c:member:`~PyConfig.user_site_directory` is non-zero and the user's
+site-package directory exists, the :mod:`site` module appends the user's
+site-package directory to :data:`sys.path`.
+
+The following configuration files are used by the path configuration:
+
+* ``pyvenv.cfg``
+* ``python._pth`` (Windows only)
+* ``pybuilddir.txt`` (Unix only)
+
+
+Py_RunMain()
+------------
+
+.. c:function:: int Py_RunMain(void)
+
+   Execute the command (:c:member:`PyConfig.run_command`), the script
+   (:c:member:`PyConfig.run_filename`) or the module
+   (:c:member:`PyConfig.run_module`) specified on the command line or in the
+   configuration.
+
+   By default and when if :option:`-i` option is used, run the REPL.
+
+   Finally, finalizes Python and returns an exit status that can be passed to
+   the ``exit()`` function.
+
+See :ref:`Python Configuration <init-python-config>` for an example of
+customized Python always running in isolated mode using
+:c:func:`Py_RunMain`.
+
+
+Multi-Phase Initialization Private Provisional API
+--------------------------------------------------
+
+This section is a private provisional API introducing multi-phase
+initialization, the core feature of the :pep:`432`:
+
+* "Core" initialization phase, "bare minimum Python":
+
+  * Builtin types;
+  * Builtin exceptions;
+  * Builtin and frozen modules;
+  * The :mod:`sys` module is only partially initialized
+    (ex: :data:`sys.path` doesn't exist yet);
+
+* "Main" initialization phase, Python is fully initialized:
+
+  * Install and configure :mod:`importlib`;
+  * Apply the :ref:`Path Configuration <init-path-config>`;
+  * Install signal handlers;
+  * Finish :mod:`sys` module initialization (ex: create :data:`sys.stdout`
+    and :data:`sys.path`);
+  * Enable optional features like :mod:`faulthandler` and :mod:`tracemalloc`;
+  * Import the :mod:`site` module;
+  * etc.
+
+Private provisional API:
+
+* :c:member:`PyConfig._init_main`: if set to 0,
+  :c:func:`Py_InitializeFromConfig` stops at the "Core" initialization phase.
+
+.. c:function:: PyStatus _Py_InitializeMain(void)
+
+   Move to the "Main" initialization phase, finish the Python initialization.
+
+No module is imported during the "Core" phase and the ``importlib`` module is
+not configured: the :ref:`Path Configuration <init-path-config>` is only
+applied during the "Main" phase. It may allow to customize Python in Python to
+override or tune the :ref:`Path Configuration <init-path-config>`, maybe
+install a custom sys.meta_path importer or an import hook, etc.
+
+It may become possible to compute the :ref:`Path Configuration
+<init-path-config>` in Python, after the Core phase and before the Main phase,
+which is one of the :pep:`432` motivation.
+
+The "Core" phase is not properly defined: what should be and what should
+not be available at this phase is not specified yet. The API is marked
+as private and provisional: the API can be modified or even be removed
+anytime until a proper public API is designed.
+
+Example running Python code between "Core" and "Main" initialization
+phases::
+
+    void init_python(void)
+    {
+        PyStatus status;
+        PyConfig config;
+
+        status = PyConfig_InitPythonConfig(&config);
+        if (PyStatus_Exception(status)) {
+            PyConfig_Clear(&config);
+            Py_ExitStatusException(status);
+        }
+
+        config._init_main = 0;
+
+        /* ... customize 'config' configuration ... */
+
+        status = Py_InitializeFromConfig(&config);
+        PyConfig_Clear(&config);
+        if (PyStatus_Exception(status)) {
+            Py_ExitStatusException(status);
+        }
+
+        /* Use sys.stderr because sys.stdout is only created
+           by _Py_InitializeMain() */
+        int res = PyRun_SimpleString(
+            "import sys; "
+            "print('Run Python code before _Py_InitializeMain', "
+                   "file=sys.stderr)");
+        if (res < 0) {
+            exit(1);
+        }
+
+        /* ... put more configuration code here ... */
+
+        status = _Py_InitializeMain();
+        if (PyStatus_Exception(status)) {
+            Py_ExitStatusException(status);
+        }
+    }
diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst
index a7ff08cfb6bd..3fe0ae47aac3 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -42,6 +42,13 @@ the same library that the Python runtime is using.
    ``Py_InspectFlag`` is not set.
 
 
+.. c:function:: int Py_BytesMain(int argc, char **argv)
+
+   Similar to :c:func:`Py_Main` but *argv* is an array of bytes strings.
+
+   .. versionadded:: 3.8
+
+
 .. c:function:: int PyRun_AnyFile(FILE *fp, const char *filename)
 
    This is a simplified interface to :c:func:`PyRun_AnyFileExFlags` below, leaving
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 1180469ff28f..6102d8c357ca 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -182,6 +182,61 @@ Would print ``x*9 + 15=42``.
 
 (Contributed by Eric V. Smith and Larry Hastings in :issue:`36817`.)
 
+PEP 587: Python Initialization Configuration
+--------------------------------------------
+
+The :pep:`587` adds a new C API to configure the Python Initialization
+providing finer control on the whole configuration and better error reporting.
+
+New structures:
+
+* :c:type:`PyConfig`
+* :c:type:`PyPreConfig`
+* :c:type:`PyStatus`
+* :c:type:`PyWideStringList`
+
+New functions:
+
+* :c:func:`PyConfig_Clear`
+* :c:func:`PyConfig_InitIsolatedConfig`
+* :c:func:`PyConfig_InitPythonConfig`
+* :c:func:`PyConfig_Read`
+* :c:func:`PyConfig_SetArgv`
+* :c:func:`PyConfig_SetBytesArgv`
+* :c:func:`PyConfig_SetBytesString`
+* :c:func:`PyConfig_SetString`
+* :c:func:`PyPreConfig_InitIsolatedConfig`
+* :c:func:`PyPreConfig_InitPythonConfig`
+* :c:func:`PyStatus_Error`
+* :c:func:`PyStatus_Exception`
+* :c:func:`PyStatus_Exit`
+* :c:func:`PyStatus_IsError`
+* :c:func:`PyStatus_IsExit`
+* :c:func:`PyStatus_NoMemory`
+* :c:func:`PyStatus_Ok`
+* :c:func:`PyWideStringList_Append`
+* :c:func:`PyWideStringList_Insert`
+* :c:func:`Py_BytesMain`
+* :c:func:`Py_ExitStatusException`
+* :c:func:`Py_InitializeFromConfig`
+* :c:func:`Py_PreInitialize`
+* :c:func:`Py_PreInitializeFromArgs`
+* :c:func:`Py_PreInitializeFromBytesArgs`
+* :c:func:`Py_RunMain`
+
+This PEP also adds ``_PyRuntimeState.preconfig`` (:c:type:`PyPreConfig` type)
+and ``PyInterpreterState.config`` (:c:type:`PyConfig` type) fields to these
+internal structures. ``PyInterpreterState.config`` becomes the new
+reference configuration, replacing global configuration variables and
+other private variables.
+
+See :ref:`Python Initialization Configuration <init-config>` for the
+documentation.
+
+See :pep:`587` for a full description.
+
+(Contributed by Victor Stinner in :issue:`36763`.)
+
 
 Other Language Changes
 ======================
diff --git a/Include/Python.h b/Include/Python.h
index 17ad5b3071d4..d6e5b139ac67 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -129,7 +129,7 @@
 #include "codecs.h"
 #include "pyerrors.h"
 
-#include "cpython/coreconfig.h"
+#include "cpython/initconfig.h"
 #include "pystate.h"
 #include "context.h"
 
diff --git a/Include/cpython/coreconfig.h b/Include/cpython/initconfig.h
similarity index 84%
rename from Include/cpython/coreconfig.h
rename to Include/cpython/initconfig.h
index ef5fde20e88d..a98b91a86943 100644
--- a/Include/cpython/coreconfig.h
+++ b/Include/cpython/initconfig.h
@@ -5,56 +5,49 @@
 extern "C" {
 #endif
 
-/* --- _PyInitError ----------------------------------------------- */
+/* --- PyStatus ----------------------------------------------- */
 
 typedef struct {
     enum {
-        _Py_INIT_ERR_TYPE_OK=0,
-        _Py_INIT_ERR_TYPE_ERROR=1,
-        _Py_INIT_ERR_TYPE_EXIT=2
+        _PyStatus_TYPE_OK=0,
+        _PyStatus_TYPE_ERROR=1,
+        _PyStatus_TYPE_EXIT=2
     } _type;
-    const char *_func;
+    const char *func;
     const char *err_msg;
     int exitcode;
-} _PyInitError;
+} PyStatus;
 
-PyAPI_FUNC(_PyInitError) _PyInitError_Ok(void);
-PyAPI_FUNC(_PyInitError) _PyInitError_Error(const char *err_msg);
-PyAPI_FUNC(_PyInitError) _PyInitError_NoMemory(void);
-PyAPI_FUNC(_PyInitError) _PyInitError_Exit(int exitcode);
-PyAPI_FUNC(int) _PyInitError_IsError(_PyInitError err);
-PyAPI_FUNC(int) _PyInitError_IsExit(_PyInitError err);
-PyAPI_FUNC(int) _PyInitError_Failed(_PyInitError err);
+PyAPI_FUNC(PyStatus) PyStatus_Ok(void);
+PyAPI_FUNC(PyStatus) PyStatus_Error(const char *err_msg);
+PyAPI_FUNC(PyStatus) PyStatus_NoMemory(void);
+PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode);
+PyAPI_FUNC(int) PyStatus_IsError(PyStatus err);
+PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err);
+PyAPI_FUNC(int) PyStatus_Exception(PyStatus err);
 
-/* --- _PyWstrList ------------------------------------------------ */
+/* --- PyWideStringList ------------------------------------------------ */
 
 typedef struct {
     /* If length is greater than zero, items must be non-NULL
        and all items strings must be non-NULL */
     Py_ssize_t length;
     wchar_t **items;
-} _PyWstrList;
+} PyWideStringList;
 
+PyAPI_FUNC(PyStatus) PyWideStringList_Append(PyWideStringList *list,
+    const wchar_t *item);
 
-/* --- _PyPreConfig ----------------------------------------------- */
-
-#define _Py_CONFIG_VERSION 1
-
-typedef enum {
-    /* Py_Initialize() API: backward compatibility with Python 3.6 and 3.7 */
-    _PyConfig_INIT_COMPAT = 1,
-    _PyConfig_INIT_PYTHON = 2,
-    _PyConfig_INIT_ISOLATED = 3
-} _PyConfigInitEnum;
 
+/* --- PyPreConfig ----------------------------------------------- */
 
 typedef struct {
     int _config_version;  /* Internal configuration version,
                              used for ABI compatibility */
     int _config_init;     /* _PyConfigInitEnum value */
 
-    /* Parse _Py_PreInitializeFromArgs() arguments?
-       See _PyCoreConfig.parse_argv */
+    /* Parse Py_PreInitializeFromBytesArgs() arguments?
+       See PyConfig.parse_argv */
     int parse_argv;
 
     /* If greater than 0, enable isolated mode: sys.path contains
@@ -124,22 +117,22 @@ typedef struct {
     /* Memory allocator: PYTHONMALLOC env var.
        See PyMemAllocatorName for valid values. */
     int allocator;
-} _PyPreConfig;
+} PyPreConfig;
 
-PyAPI_FUNC(void) _PyPreConfig_InitPythonConfig(_PyPreConfig *config);
-PyAPI_FUNC(void) _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config);
+PyAPI_FUNC(void) PyPreConfig_InitPythonConfig(PyPreConfig *config);
+PyAPI_FUNC(void) PyPreConfig_InitIsolatedConfig(PyPreConfig *config);
 
 
-/* --- _PyCoreConfig ---------------------------------------------- */
+/* --- PyConfig ---------------------------------------------- */
 
 typedef struct {
     int _config_version;  /* Internal configuration version,
                              used for ABI compatibility */
     int _config_init;     /* _PyConfigInitEnum value */
 
-    int isolated;         /* Isolated mode? see _PyPreConfig.isolated */
-    int use_environment;  /* Use environment variables? see _PyPreConfig.use_environment */
-    int dev_mode;         /* Development mode? See _PyPreConfig.dev_mode */
+    int isolated;         /* Isolated mode? see PyPreConfig.isolated */
+    int use_environment;  /* Use environment variables? see PyPreConfig.use_environment */
+    int dev_mode;         /* Development mode? See PyPreConfig.dev_mode */
 
     /* Install signal handlers? Yes by default. */
     int install_signal_handlers;
@@ -207,7 +200,7 @@ typedef struct {
 
        If argv is empty, an empty string is added to ensure that sys.argv
        always exists and is never empty. */
-    _PyWstrList argv;
+    PyWideStringList argv;
 
     /* Program name:
 
@@ -219,8 +212,8 @@ typedef struct {
        - Use "python" on Windows, or "python3 on other platforms. */
     wchar_t *program_name;
 
-    _PyWstrList xoptions;     /* Command line -X options */
-    _PyWstrList warnoptions;  /* Warnings options */
+    PyWideStringList xoptions;     /* Command line -X options */
+    PyWideStringList warnoptions;  /* Warnings options */
 
     /* If equal to zero, disable the import of the module site and the
        site-dependent manipulations of sys.path that it entails. Also disable
@@ -347,17 +340,37 @@ typedef struct {
     int legacy_windows_stdio;
 #endif
 
+    /* Value of the --check-hash-based-pycs command line option:
+
+       - "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
+
+       The default value is "default".
+
+       See PEP 552 "Deterministic pycs" for more details. */
+    wchar_t *check_hash_pycs_mode;
+
     /* --- Path configuration inputs ------------ */
 
-    wchar_t *module_search_path_env; /* PYTHONPATH environment variable */
+    /* If greater than 0, suppress _PyPathConfig_Calculate() warnings on Unix.
+       The parameter has no effect on Windows.
+
+       If set to -1 (default), inherit !Py_FrozenFlag value. */
+    int pathconfig_warnings;
+
+    wchar_t *pythonpath_env; /* PYTHONPATH environment variable */
     wchar_t *home;          /* PYTHONHOME environment variable,
                                see also Py_SetPythonHome(). */
 
     /* --- Path configuration outputs ----------- */
 
-    int use_module_search_paths;  /* If non-zero, use module_search_paths */
-    _PyWstrList module_search_paths;  /* sys.path paths. Computed if
-                                       use_module_search_paths is equal
+    int module_search_paths_set;  /* If non-zero, use module_search_paths */
+    PyWideStringList module_search_paths;  /* sys.path paths. Computed if
+                                       module_search_paths_set is equal
                                        to zero. */
 
     wchar_t *executable;    /* sys.executable */
@@ -384,48 +397,28 @@ typedef struct {
        Needed by freeze_importlib. */
     int _install_importlib;
 
-    /* Value of the --check-hash-based-pycs command line option:
-
-       - "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
-
-       The default value is "default".
-
-       See PEP 552 "Deterministic pycs" for more details. */
-    wchar_t *check_hash_pycs_mode;
-
-    /* If greater than 0, suppress _PyPathConfig_Calculate() warnings on Unix.
-       The parameter has no effect on Windows.
-
-       If set to -1 (default), inherit !Py_FrozenFlag value. */
-    int pathconfig_warnings;
-
     /* If equal to 0, stop Python initialization before the "main" phase */
     int _init_main;
 
-} _PyCoreConfig;
+} PyConfig;
 
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config);
-PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetString(
-    _PyCoreConfig *config,
+PyAPI_FUNC(PyStatus) PyConfig_InitPythonConfig(PyConfig *config);
+PyAPI_FUNC(PyStatus) PyConfig_InitIsolatedConfig(PyConfig *config);
+PyAPI_FUNC(void) PyConfig_Clear(PyConfig *);
+PyAPI_FUNC(PyStatus) PyConfig_SetString(
+    PyConfig *config,
     wchar_t **config_str,
     const wchar_t *str);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_DecodeLocale(
-    _PyCoreConfig *config,
+PyAPI_FUNC(PyStatus) PyConfig_SetBytesString(
+    PyConfig *config,
     wchar_t **config_str,
     const char *str);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetArgv(
-    _PyCoreConfig *config,
+PyAPI_FUNC(PyStatus) PyConfig_Read(PyConfig *config);
+PyAPI_FUNC(PyStatus) PyConfig_SetBytesArgv(
+    PyConfig *config,
     Py_ssize_t argc,
     char * const *argv);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetWideArgv(_PyCoreConfig *config,
+PyAPI_FUNC(PyStatus) PyConfig_SetArgv(PyConfig *config,
     Py_ssize_t argc,
     wchar_t * const *argv);
 
diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h
index ba5666465d7e..2f3a0dbdfe64 100644
--- a/Include/cpython/pylifecycle.h
+++ b/Include/cpython/pylifecycle.h
@@ -14,14 +14,14 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
 
 /* PEP 432 Multi-phase initialization API (Private while provisional!) */
 
-PyAPI_FUNC(_PyInitError) _Py_PreInitialize(
-    const _PyPreConfig *src_config);
-PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromArgs(
-    const _PyPreConfig *src_config,
+PyAPI_FUNC(PyStatus) Py_PreInitialize(
+    const PyPreConfig *src_config);
+PyAPI_FUNC(PyStatus) Py_PreInitializeFromBytesArgs(
+    const PyPreConfig *src_config,
     Py_ssize_t argc,
     char **argv);
-PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromWideArgs(
-    const _PyPreConfig *src_config,
+PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs(
+    const PyPreConfig *src_config,
     Py_ssize_t argc,
     wchar_t **argv);
 
@@ -30,22 +30,22 @@ PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
 
 /* Initialization and finalization */
 
-PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig(
-    const _PyCoreConfig *config);
-PyAPI_FUNC(_PyInitError) _Py_InitializeFromArgs(
-    const _PyCoreConfig *config,
+PyAPI_FUNC(PyStatus) Py_InitializeFromConfig(
+    const PyConfig *config);
+PyAPI_FUNC(PyStatus) _Py_InitializeFromArgs(
+    const PyConfig *config,
     Py_ssize_t argc,
     char * const *argv);
-PyAPI_FUNC(_PyInitError) _Py_InitializeFromWideArgs(
-    const _PyCoreConfig *config,
+PyAPI_FUNC(PyStatus) _Py_InitializeFromWideArgs(
+    const PyConfig *config,
     Py_ssize_t argc,
     wchar_t * const *argv);
-PyAPI_FUNC(_PyInitError) _Py_InitializeMain(void);
+PyAPI_FUNC(PyStatus) _Py_InitializeMain(void);
 
-PyAPI_FUNC(int) _Py_RunMain(void);
+PyAPI_FUNC(int) Py_RunMain(void);
 
 
-PyAPI_FUNC(void) _Py_NO_RETURN _Py_ExitInitError(_PyInitError err);
+PyAPI_FUNC(void) _Py_NO_RETURN Py_ExitStatusException(PyStatus err);
 
 /* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level
  * exit functions.
diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h
index 94331f35e1bd..6b7663fe3315 100644
--- a/Include/cpython/pystate.h
+++ b/Include/cpython/pystate.h
@@ -6,13 +6,11 @@
 extern "C" {
 #endif
 
-#include "cpython/coreconfig.h"
+#include "cpython/initconfig.h"
 
 PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *);
 PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int);
 
-PyAPI_FUNC(_PyCoreConfig *) _PyInterpreterState_GetCoreConfig(PyInterpreterState *);
-
 PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *);
 
 /* State unique per thread */
diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h
deleted file mode 100644
index b17737a90ba3..000000000000
--- a/Include/internal/pycore_coreconfig.h
+++ /dev/null
@@ -1,163 +0,0 @@
-#ifndef Py_INTERNAL_CORECONFIG_H
-#define Py_INTERNAL_CORECONFIG_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef Py_BUILD_CORE
-#  error "this header requires Py_BUILD_CORE define"
-#endif
-
-#include "pycore_pystate.h"   /* _PyRuntimeState */
-
-/* --- _PyInitError ----------------------------------------------- */
-
-/* Almost all errors causing Python initialization to fail */
-#ifdef _MSC_VER
-   /* Visual Studio 2015 doesn't implement C99 __func__ in C */
-#  define _Py_INIT_GET_FUNC() __FUNCTION__
-#else
-#  define _Py_INIT_GET_FUNC() __func__
-#endif
-
-#define _Py_INIT_OK() \
-    (_PyInitError){._type = _Py_INIT_ERR_TYPE_OK,}
-    /* other fields are set to 0 */
-#define _Py_INIT_ERR(ERR_MSG) \
-    (_PyInitError){ \
-        ._type = _Py_INIT_ERR_TYPE_ERROR, \
-        ._func = _Py_INIT_GET_FUNC(), \
-        .err_msg = (ERR_MSG)}
-        /* other fields are set to 0 */
-#define _Py_INIT_NO_MEMORY() _Py_INIT_ERR("memory allocation failed")
-#define _Py_INIT_EXIT(EXITCODE) \
-    (_PyInitError){ \
-        ._type = _Py_INIT_ERR_TYPE_EXIT, \
-        .exitcode = (EXITCODE)}
-#define _Py_INIT_IS_ERROR(err) \
-    (err._type == _Py_INIT_ERR_TYPE_ERROR)
-#define _Py_INIT_IS_EXIT(err) \
-    (err._type == _Py_INIT_ERR_TYPE_EXIT)
-#define _Py_INIT_FAILED(err) \
-    (err._type != _Py_INIT_ERR_TYPE_OK)
-
-/* --- _PyWstrList ------------------------------------------------ */
-
-#define _PyWstrList_INIT (_PyWstrList){.length = 0, .items = NULL}
-
-#ifndef NDEBUG
-PyAPI_FUNC(int) _PyWstrList_CheckConsistency(const _PyWstrList *list);
-#endif
-PyAPI_FUNC(void) _PyWstrList_Clear(_PyWstrList *list);
-PyAPI_FUNC(int) _PyWstrList_Copy(_PyWstrList *list,
-    const _PyWstrList *list2);
-PyAPI_FUNC(int) _PyWstrList_Append(_PyWstrList *list,
-    const wchar_t *item);
-PyAPI_FUNC(PyObject*) _PyWstrList_AsList(const _PyWstrList *list);
-PyAPI_FUNC(int) _PyWstrList_Extend(_PyWstrList *list,
-    const _PyWstrList *list2);
-
-
-/* --- _PyArgv ---------------------------------------------------- */
-
-typedef struct {
-    Py_ssize_t argc;
-    int use_bytes_argv;
-    char * const *bytes_argv;
-    wchar_t * const *wchar_argv;
-} _PyArgv;
-
-PyAPI_FUNC(_PyInitError) _PyArgv_AsWstrList(const _PyArgv *args,
-    _PyWstrList *list);
-
-
-/* --- Helper functions ------------------------------------------- */
-
-PyAPI_FUNC(int) _Py_str_to_int(
-    const char *str,
-    int *result);
-PyAPI_FUNC(const wchar_t*) _Py_get_xoption(
-    const _PyWstrList *xoptions,
-    const wchar_t *name);
-PyAPI_FUNC(const char*) _Py_GetEnv(
-    int use_environment,
-    const char *name);
-PyAPI_FUNC(void) _Py_get_env_flag(
-    int use_environment,
-    int *flag,
-    const char *name);
-
-/* Py_GetArgcArgv() helper */
-PyAPI_FUNC(void) _Py_ClearArgcArgv(void);
-
-
-/* --- _PyPreCmdline ------------------------------------------------- */
-
-typedef struct {
-    _PyWstrList argv;
-    _PyWstrList xoptions;     /* "-X value" option */
-    int isolated;             /* -I option */
-    int use_environment;      /* -E option */
-    int dev_mode;             /* -X dev and PYTHONDEVMODE */
-} _PyPreCmdline;
-
-#define _PyPreCmdline_INIT \
-    (_PyPreCmdline){ \
-        .use_environment = -1, \
-        .isolated = -1, \
-        .dev_mode = -1}
-/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */
-
-PyAPI_FUNC(void) _PyPreCmdline_Clear(_PyPreCmdline *cmdline);
-PyAPI_FUNC(_PyInitError) _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline,
-    const _PyArgv *args);
-PyAPI_FUNC(int) _PyPreCmdline_SetCoreConfig(
-    const _PyPreCmdline *cmdline,
-    _PyCoreConfig *config);
-PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline,
-    const _PyPreConfig *preconfig);
-
-
-/* --- _PyPreConfig ----------------------------------------------- */
-
-PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(_PyPreConfig *config);
-PyAPI_FUNC(void) _PyPreConfig_InitFromCoreConfig(
-    _PyPreConfig *config,
-    const _PyCoreConfig *coreconfig);
-PyAPI_FUNC(void) _PyPreConfig_InitFromPreConfig(
-    _PyPreConfig *config,
-    const _PyPreConfig *config2);
-PyAPI_FUNC(void) _PyPreConfig_Copy(_PyPreConfig *config,
-    const _PyPreConfig *config2);
-PyAPI_FUNC(PyObject*) _PyPreConfig_AsDict(const _PyPreConfig *config);
-PyAPI_FUNC(void) _PyPreConfig_GetCoreConfig(_PyPreConfig *config,
-    const _PyCoreConfig *core_config);
-PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config,
-    const _PyArgv *args);
-PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(const _PyPreConfig *config);
-
-
-/* --- _PyCoreConfig ---------------------------------------------- */
-
-PyAPI_FUNC(void) _PyCoreConfig_InitCompatConfig(_PyCoreConfig *config);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_Copy(
-    _PyCoreConfig *config,
-    const _PyCoreConfig *config2);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig(
-    const _PyCoreConfig *config);
-PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config,
-    _PyRuntimeState *runtime);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPyArgv(
-    _PyCoreConfig *config,
-    const _PyArgv *args);
-
-
-/* --- Function used for testing ---------------------------------- */
-
-PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* !Py_INTERNAL_CORECONFIG_H */
diff --git a/Include/internal/pycore_initconfig.h b/Include/internal/pycore_initconfig.h
new file mode 100644
index 000000000000..c0b3d957827a
--- /dev/null
+++ b/Include/internal/pycore_initconfig.h
@@ -0,0 +1,168 @@
+#ifndef Py_INTERNAL_CORECONFIG_H
+#define Py_INTERNAL_CORECONFIG_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_pystate.h"   /* _PyRuntimeState */
+
+/* --- PyStatus ----------------------------------------------- */
+
+/* Almost all errors causing Python initialization to fail */
+#ifdef _MSC_VER
+   /* Visual Studio 2015 doesn't implement C99 __func__ in C */
+#  define _PyStatus_GET_FUNC() __FUNCTION__
+#else
+#  define _PyStatus_GET_FUNC() __func__
+#endif
+
+#define _PyStatus_OK() \
+    (PyStatus){._type = _PyStatus_TYPE_OK,}
+    /* other fields are set to 0 */
+#define _PyStatus_ERR(ERR_MSG) \
+    (PyStatus){ \
+        ._type = _PyStatus_TYPE_ERROR, \
+        .func = _PyStatus_GET_FUNC(), \
+        .err_msg = (ERR_MSG)}
+        /* other fields are set to 0 */
+#define _PyStatus_NO_MEMORY() _PyStatus_ERR("memory allocation failed")
+#define _PyStatus_EXIT(EXITCODE) \
+    (PyStatus){ \
+        ._type = _PyStatus_TYPE_EXIT, \
+        .exitcode = (EXITCODE)}
+#define _PyStatus_IS_ERROR(err) \
+    (err._type == _PyStatus_TYPE_ERROR)
+#define _PyStatus_IS_EXIT(err) \
+    (err._type == _PyStatus_TYPE_EXIT)
+#define _PyStatus_EXCEPTION(err) \
+    (err._type != _PyStatus_TYPE_OK)
+
+/* --- PyWideStringList ------------------------------------------------ */
+
+#define PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL}
+
+#ifndef NDEBUG
+PyAPI_FUNC(int) _PyWideStringList_CheckConsistency(const PyWideStringList *list);
+#endif
+PyAPI_FUNC(void) _PyWideStringList_Clear(PyWideStringList *list);
+PyAPI_FUNC(int) _PyWideStringList_Copy(PyWideStringList *list,
+    const PyWideStringList *list2);
+PyAPI_FUNC(PyStatus) _PyWideStringList_Extend(PyWideStringList *list,
+    const PyWideStringList *list2);
+PyAPI_FUNC(PyObject*) _PyWideStringList_AsList(const PyWideStringList *list);
+
+
+/* --- _PyArgv ---------------------------------------------------- */
+
+typedef struct {
+    Py_ssize_t argc;
+    int use_bytes_argv;
+    char * const *bytes_argv;
+    wchar_t * const *wchar_argv;
+} _PyArgv;
+
+PyAPI_FUNC(PyStatus) _PyArgv_AsWstrList(const _PyArgv *args,
+    PyWideStringList *list);
+
+
+/* --- Helper functions ------------------------------------------- */
+
+PyAPI_FUNC(int) _Py_str_to_int(
+    const char *str,
+    int *result);
+PyAPI_FUNC(const wchar_t*) _Py_get_xoption(
+    const PyWideStringList *xoptions,
+    const wchar_t *name);
+PyAPI_FUNC(const char*) _Py_GetEnv(
+    int use_environment,
+    const char *name);
+PyAPI_FUNC(void) _Py_get_env_flag(
+    int use_environment,
+    int *flag,
+    const char *name);
+
+/* Py_GetArgcArgv() helper */
+PyAPI_FUNC(void) _Py_ClearArgcArgv(void);
+
+
+/* --- _PyPreCmdline ------------------------------------------------- */
+
+typedef struct {
+    PyWideStringList argv;
+    PyWideStringList xoptions;     /* "-X value" option */
+    int isolated;             /* -I option */
+    int use_environment;      /* -E option */
+    int dev_mode;             /* -X dev and PYTHONDEVMODE */
+} _PyPreCmdline;
+
+#define _PyPreCmdline_INIT \
+    (_PyPreCmdline){ \
+        .use_environment = -1, \
+        .isolated = -1, \
+        .dev_mode = -1}
+/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */
+
+extern void _PyPreCmdline_Clear(_PyPreCmdline *cmdline);
+extern PyStatus _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline,
+    const _PyArgv *args);
+extern PyStatus _PyPreCmdline_SetConfig(
+    const _PyPreCmdline *cmdline,
+    PyConfig *config);
+extern PyStatus _PyPreCmdline_Read(_PyPreCmdline *cmdline,
+    const PyPreConfig *preconfig);
+
+
+/* --- PyPreConfig ----------------------------------------------- */
+
+PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(PyPreConfig *preconfig);
+extern void _PyPreConfig_InitFromConfig(
+    PyPreConfig *preconfig,
+    const PyConfig *config);
+extern void _PyPreConfig_InitFromPreConfig(
+    PyPreConfig *preconfig,
+    const PyPreConfig *config2);
+extern PyObject* _PyPreConfig_AsDict(const PyPreConfig *preconfig);
+extern void _PyPreConfig_GetConfig(PyPreConfig *preconfig,
+    const PyConfig *config);
+extern PyStatus _PyPreConfig_Read(PyPreConfig *preconfig,
+    const _PyArgv *args);
+extern PyStatus _PyPreConfig_Write(const PyPreConfig *preconfig);
+
+
+/* --- PyConfig ---------------------------------------------- */
+
+#define _Py_CONFIG_VERSION 1
+
+typedef enum {
+    /* Py_Initialize() API: backward compatibility with Python 3.6 and 3.7 */
+    _PyConfig_INIT_COMPAT = 1,
+    _PyConfig_INIT_PYTHON = 2,
+    _PyConfig_INIT_ISOLATED = 3
+} _PyConfigInitEnum;
+
+PyAPI_FUNC(void) _PyConfig_InitCompatConfig(PyConfig *config);
+extern PyStatus _PyConfig_Copy(
+    PyConfig *config,
+    const PyConfig *config2);
+extern PyStatus _PyConfig_InitPathConfig(PyConfig *config);
+extern PyStatus _PyConfig_SetPathConfig(
+    const PyConfig *config);
+extern void _PyConfig_Write(const PyConfig *config,
+    _PyRuntimeState *runtime);
+extern PyStatus _PyConfig_SetPyArgv(
+    PyConfig *config,
+    const _PyArgv *args);
+
+
+/* --- Function used for testing ---------------------------------- */
+
+PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_CORECONFIG_H */
diff --git a/Include/internal/pycore_pathconfig.h b/Include/internal/pycore_pathconfig.h
index bee391187cc9..be12c6f5cf32 100644
--- a/Include/internal/pycore_pathconfig.h
+++ b/Include/internal/pycore_pathconfig.h
@@ -37,17 +37,17 @@ typedef struct _PyPathConfig {
 
 PyAPI_DATA(_PyPathConfig) _Py_path_config;
 
-PyAPI_FUNC(void) _PyPathConfig_ClearGlobal(void);
-PyAPI_FUNC(_PyInitError) _PyPathConfig_SetGlobal(
-    const struct _PyPathConfig *config);
-
-PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate_impl(
-    _PyPathConfig *config,
-    const _PyCoreConfig *core_config);
-PyAPI_FUNC(int) _PyPathConfig_ComputeSysPath0(
-    const _PyWstrList *argv,
+extern void _PyPathConfig_ClearGlobal(void);
+extern PyStatus _PyPathConfig_SetGlobal(
+    const struct _PyPathConfig *pathconfig);
+
+extern PyStatus _PyPathConfig_Calculate(
+    _PyPathConfig *pathconfig,
+    const PyConfig *config);
+extern int _PyPathConfig_ComputeSysPath0(
+    const PyWideStringList *argv,
     PyObject **path0);
-PyAPI_FUNC(int) _Py_FindEnvConfigValue(
+extern int _Py_FindEnvConfigValue(
     FILE *env_file,
     const wchar_t *key,
     wchar_t *value,
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 13a31c262da8..69761cef9822 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -8,20 +8,20 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
-#include "pycore_coreconfig.h"   /* _PyArgv */
+#include "pycore_initconfig.h"   /* _PyArgv */
 #include "pycore_pystate.h"      /* _PyRuntimeState */
 
 /* True if the main interpreter thread exited due to an unhandled
  * KeyboardInterrupt exception, suggesting the user pressed ^C. */
 PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt;
 
-PyAPI_FUNC(int) _Py_UnixMain(int argc, char **argv);
+PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv);
 
 extern int _Py_SetFileSystemEncoding(
     const char *encoding,
     const char *errors);
 extern void _Py_ClearFileSystemEncoding(void);
-extern _PyInitError _PyUnicode_InitEncodings(PyInterpreterState *interp);
+extern PyStatus _PyUnicode_InitEncodings(PyInterpreterState *interp);
 #ifdef MS_WINDOWS
 extern int _PyUnicode_EnableLegacyWindowsFSEncoding(void);
 #endif
@@ -32,30 +32,30 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);
 
 /* Various one-time initializers */
 
-extern _PyInitError _PyUnicode_Init(void);
+extern PyStatus _PyUnicode_Init(void);
 extern int _PyStructSequence_Init(void);
 extern int _PyLong_Init(void);
-extern _PyInitError _PyFaulthandler_Init(int enable);
+extern PyStatus _PyFaulthandler_Init(int enable);
 extern int _PyTraceMalloc_Init(int enable);
 extern PyObject * _PyBuiltin_Init(void);
-extern _PyInitError _PySys_Create(
+extern PyStatus _PySys_Create(
     _PyRuntimeState *runtime,
     PyInterpreterState *interp,
     PyObject **sysmod_p);
-extern _PyInitError _PySys_SetPreliminaryStderr(PyObject *sysdict);
+extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict);
 extern int _PySys_InitMain(
     _PyRuntimeState *runtime,
     PyInterpreterState *interp);
-extern _PyInitError _PyImport_Init(PyInterpreterState *interp);
-extern _PyInitError _PyExc_Init(void);
-extern _PyInitError _PyErr_Init(void);
-extern _PyInitError _PyBuiltins_AddExceptions(PyObject * bltinmod);
-extern _PyInitError _PyImportHooks_Init(void);
+extern PyStatus _PyImport_Init(PyInterpreterState *interp);
+extern PyStatus _PyExc_Init(void);
+extern PyStatus _PyErr_Init(void);
+extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod);
+extern PyStatus _PyImportHooks_Init(void);
 extern int _PyFloat_Init(void);
-extern _PyInitError _Py_HashRandomization_Init(const _PyCoreConfig *);
+extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
 
-extern _PyInitError _PyTypes_Init(void);
-extern _PyInitError _PyImportZip_Init(PyInterpreterState *interp);
+extern PyStatus _PyTypes_Init(void);
+extern PyStatus _PyImportZip_Init(PyInterpreterState *interp);
 
 
 /* Various internal finalizers */
@@ -94,11 +94,11 @@ extern void _PyGILState_Fini(_PyRuntimeState *runtime);
 
 PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime);
 
-PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPyArgv(
-    const _PyPreConfig *src_config,
+PyAPI_FUNC(PyStatus) _Py_PreInitializeFromPyArgv(
+    const PyPreConfig *src_config,
     const _PyArgv *args);
-PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromCoreConfig(
-    const _PyCoreConfig *coreconfig,
+PyAPI_FUNC(PyStatus) _Py_PreInitializeFromConfig(
+    const PyConfig *config,
     const _PyArgv *args);
 
 
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index ef1d8a061f17..3ab4009770c9 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -8,7 +8,7 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
-#include "cpython/coreconfig.h"
+#include "cpython/initconfig.h"
 #include "fileobject.h"
 #include "pystate.h"
 #include "pythread.h"
@@ -106,7 +106,7 @@ struct _is {
         _Py_error_handler error_handler;
     } fs_codec;
 
-    _PyCoreConfig core_config;
+    PyConfig config;
 #ifdef HAVE_DLOPEN
     int dlopenflags;
 #endif
@@ -193,7 +193,7 @@ struct _gilstate_runtime_state {
 /* Full Python runtime state */
 
 typedef struct pyruntimestate {
-    /* Is Python pre-initialized? Set to 1 by _Py_PreInitialize() */
+    /* Is Python pre-initialized? Set to 1 by Py_PreInitialize() */
     int pre_initialized;
 
     /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */
@@ -234,7 +234,7 @@ typedef struct pyruntimestate {
     struct _ceval_runtime_state ceval;
     struct _gilstate_runtime_state gilstate;
 
-    _PyPreConfig preconfig;
+    PyPreConfig preconfig;
 
     Py_OpenCodeHookFunction open_code_hook;
     void *open_code_userdata;
@@ -248,13 +248,13 @@ typedef struct pyruntimestate {
 /* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */
 
 PyAPI_DATA(_PyRuntimeState) _PyRuntime;
-PyAPI_FUNC(_PyInitError) _PyRuntimeState_Init(_PyRuntimeState *runtime);
+PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime);
 PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
 PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
 
 /* Initialize _PyRuntimeState.
    Return NULL on success, or return an error message on failure. */
-PyAPI_FUNC(_PyInitError) _PyRuntime_Initialize(void);
+PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void);
 
 PyAPI_FUNC(void) _PyRuntime_Finalize(void);
 
@@ -307,7 +307,7 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(
     struct _gilstate_runtime_state *gilstate,
     PyThreadState *newts);
 
-PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
+PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
 PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);
 
 PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime);
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index 87e90f74bb13..a39ef2babbdb 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -272,7 +272,7 @@ def test_initialize_pymain(self):
 
     def test_run_main(self):
         out, err = self.run_embedded_interpreter("test_run_main")
-        self.assertEqual(out.rstrip(), "_Py_RunMain(): sys.argv=['-c', 'arg2']")
+        self.assertEqual(out.rstrip(), "Py_RunMain(): sys.argv=['-c', 'arg2']")
         self.assertEqual(err, '')
 
 
@@ -321,7 +321,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         'use_environment',
     ]
 
-    CORE_CONFIG_COMPAT = {
+    CONFIG_COMPAT = {
         '_config_init': API_COMPAT,
         'isolated': 0,
         'use_environment': 1,
@@ -349,7 +349,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         'xoptions': [],
         'warnoptions': [],
 
-        'module_search_path_env': None,
+        'pythonpath_env': None,
         'home': None,
         'executable': GET_DEFAULT_CONFIG,
 
@@ -386,16 +386,16 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         '_init_main': 1,
     }
     if MS_WINDOWS:
-        CORE_CONFIG_COMPAT.update({
+        CONFIG_COMPAT.update({
             'legacy_windows_stdio': 0,
         })
 
-    CORE_CONFIG_PYTHON = dict(CORE_CONFIG_COMPAT,
+    CONFIG_PYTHON = dict(CONFIG_COMPAT,
         _config_init=API_PYTHON,
         configure_c_stdio=1,
         parse_argv=1,
     )
-    CORE_CONFIG_ISOLATED = dict(CORE_CONFIG_COMPAT,
+    CONFIG_ISOLATED = dict(CONFIG_COMPAT,
         _config_init=API_ISOLATED,
         isolated=1,
         use_environment=0,
@@ -408,7 +408,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         pathconfig_warnings=0,
     )
     if MS_WINDOWS:
-        CORE_CONFIG_ISOLATED['legacy_windows_stdio'] = 0
+        CONFIG_ISOLATED['legacy_windows_stdio'] = 0
 
     # global config
     DEFAULT_GLOBAL_CONFIG = {
@@ -535,12 +535,12 @@ def get_expected_config(self, expected_preconfig, expected, env, api,
         if expected['program_name'] is self.GET_DEFAULT_CONFIG:
             expected['program_name'] = './_testembed'
 
-        core_config = configs['core_config']
+        config = configs['config']
         for key, value in expected.items():
             if value is self.GET_DEFAULT_CONFIG:
-                expected[key] = core_config[key]
+                expected[key] = config[key]
 
-        prepend_path = expected['module_search_path_env']
+        prepend_path = expected['pythonpath_env']
         if prepend_path is not None:
             expected['module_search_paths'] = [prepend_path, *expected['module_search_paths']]
         if add_path is not None:
@@ -550,34 +550,34 @@ def get_expected_config(self, expected_preconfig, expected, env, api,
             if key not in expected_preconfig:
                 expected_preconfig[key] = expected[key]
 
-    def check_pre_config(self, config, expected):
-        pre_config = dict(config['pre_config'])
+    def check_pre_config(self, configs, expected):
+        pre_config = dict(configs['pre_config'])
         for key, value in list(expected.items()):
             if value is self.IGNORE_CONFIG:
                 del pre_config[key]
                 del expected[key]
         self.assertEqual(pre_config, expected)
 
-    def check_core_config(self, config, expected):
-        core_config = dict(config['core_config'])
+    def check_config(self, configs, expected):
+        config = dict(configs['config'])
         for key, value in list(expected.items()):
             if value is self.IGNORE_CONFIG:
-                del core_config[key]
+                del config[key]
                 del expected[key]
-        self.assertEqual(core_config, expected)
+        self.assertEqual(config, expected)
 
-    def check_global_config(self, config):
-        pre_config = config['pre_config']
-        core_config = config['core_config']
+    def check_global_config(self, configs):
+        pre_config = configs['pre_config']
+        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 core_config[core_key] else 1
+                expected[global_key] = 0 if config[core_key] else 1
             else:
                 global_key, core_key = item
-                expected[global_key] = core_config[core_key]
+                expected[global_key] = config[core_key]
         for item in self.COPY_GLOBAL_PRE_CONFIG:
             if len(item) == 3:
                 global_key, core_key, opposite = item
@@ -586,9 +586,9 @@ def check_global_config(self, config):
                 global_key, core_key = item
                 expected[global_key] = pre_config[core_key]
 
-        self.assertEqual(config['global_config'], expected)
+        self.assertEqual(configs['global_config'], expected)
 
-    def check_config(self, testname, expected_config=None,
+    def check_all_configs(self, testname, expected_config=None,
                      expected_preconfig=None, add_path=None, stderr=None,
                      *, api):
         env = dict(os.environ)
@@ -610,11 +610,11 @@ def check_config(self, testname, expected_config=None,
             expected_config = {}
 
         if api == API_PYTHON:
-            default_config = self.CORE_CONFIG_PYTHON
+            default_config = self.CONFIG_PYTHON
         elif api == API_ISOLATED:
-            default_config = self.CORE_CONFIG_ISOLATED
+            default_config = self.CONFIG_ISOLATED
         else:
-            default_config = self.CORE_CONFIG_COMPAT
+            default_config = self.CONFIG_COMPAT
         expected_config = dict(default_config, **expected_config)
 
         self.get_expected_config(expected_preconfig,
@@ -627,22 +627,22 @@ def check_config(self, testname, expected_config=None,
         if stderr is not None:
             self.assertEqual(err.rstrip(), stderr)
         try:
-            config = json.loads(out)
+            configs = json.loads(out)
         except json.JSONDecodeError:
             self.fail(f"fail to decode stdout: {out!r}")
 
-        self.check_pre_config(config, expected_preconfig)
-        self.check_core_config(config, expected_config)
-        self.check_global_config(config)
+        self.check_pre_config(configs, expected_preconfig)
+        self.check_config(configs, expected_config)
+        self.check_global_config(configs)
 
     def test_init_default_config(self):
-        self.check_config("test_init_initialize_config", api=API_COMPAT)
+        self.check_all_configs("test_init_initialize_config", api=API_COMPAT)
 
     def test_preinit_compat_config(self):
-        self.check_config("test_preinit_compat_config", api=API_COMPAT)
+        self.check_all_configs("test_preinit_compat_config", api=API_COMPAT)
 
     def test_init_compat_config(self):
-        self.check_config("test_init_compat_config", api=API_COMPAT)
+        self.check_all_configs("test_init_compat_config", api=API_COMPAT)
 
     def test_init_global_config(self):
         preconfig = {
@@ -664,8 +664,8 @@ def test_init_global_config(self):
             'user_site_directory': 0,
             'pathconfig_warnings': 0,
         }
-        self.check_config("test_init_global_config", config, preconfig,
-                          api=API_COMPAT)
+        self.check_all_configs("test_init_global_config", config, preconfig,
+                               api=API_COMPAT)
 
     def test_init_from_config(self):
         preconfig = {
@@ -689,7 +689,7 @@ def test_init_from_config(self):
             'program_name': './conf_program_name',
             'argv': ['-c', 'arg2'],
             'parse_argv': 1,
-            'xoptions': ['core_xoption1=3', 'core_xoption2=', 'core_xoption3'],
+            'xoptions': ['xoption1=3', 'xoption2=', 'xoption3'],
             'warnoptions': ['error::ResourceWarning', 'default::BytesWarning'],
             'run_command': 'pass\n',
 
@@ -709,8 +709,8 @@ def test_init_from_config(self):
             'check_hash_pycs_mode': 'always',
             'pathconfig_warnings': 0,
         }
-        self.check_config("test_init_from_config", config, preconfig,
-                          api=API_COMPAT)
+        self.check_all_configs("test_init_from_config", config, preconfig,
+                               api=API_COMPAT)
 
     def test_init_compat_env(self):
         preconfig = {
@@ -724,7 +724,7 @@ def test_init_compat_env(self):
             'malloc_stats': 1,
             'inspect': 1,
             'optimization_level': 2,
-            'module_search_path_env': '/my/path',
+            'pythonpath_env': '/my/path',
             'pycache_prefix': 'env_pycache_prefix',
             'write_bytecode': 0,
             'verbose': 1,
@@ -735,8 +735,8 @@ def test_init_compat_env(self):
             'faulthandler': 1,
             'warnoptions': ['EnvVar'],
         }
-        self.check_config("test_init_compat_env", config, preconfig,
-                          api=API_COMPAT)
+        self.check_all_configs("test_init_compat_env", config, preconfig,
+                               api=API_COMPAT)
 
     def test_init_python_env(self):
         preconfig = {
@@ -751,7 +751,7 @@ def test_init_python_env(self):
             'malloc_stats': 1,
             'inspect': 1,
             'optimization_level': 2,
-            'module_search_path_env': '/my/path',
+            'pythonpath_env': '/my/path',
             'pycache_prefix': 'env_pycache_prefix',
             'write_bytecode': 0,
             'verbose': 1,
@@ -762,24 +762,24 @@ def test_init_python_env(self):
             'faulthandler': 1,
             'warnoptions': ['EnvVar'],
         }
-        self.check_config("test_init_python_env", config, preconfig,
-                          api=API_PYTHON)
+        self.check_all_configs("test_init_python_env", config, preconfig,
+                               api=API_PYTHON)
 
     def test_init_env_dev_mode(self):
         preconfig = dict(allocator=PYMEM_ALLOCATOR_DEBUG)
         config = dict(dev_mode=1,
                       faulthandler=1,
                       warnoptions=['default'])
-        self.check_config("test_init_env_dev_mode", config, preconfig,
-                          api=API_COMPAT)
+        self.check_all_configs("test_init_env_dev_mode", config, preconfig,
+                               api=API_COMPAT)
 
     def test_init_env_dev_mode_alloc(self):
         preconfig = dict(allocator=PYMEM_ALLOCATOR_MALLOC)
         config = dict(dev_mode=1,
                       faulthandler=1,
                       warnoptions=['default'])
-        self.check_config("test_init_env_dev_mode_alloc", config, preconfig,
-                          api=API_COMPAT)
+        self.check_all_configs("test_init_env_dev_mode_alloc", config, preconfig,
+                               api=API_COMPAT)
 
     def test_init_dev_mode(self):
         preconfig = {
@@ -790,8 +790,8 @@ def test_init_dev_mode(self):
             'dev_mode': 1,
             'warnoptions': ['default'],
         }
-        self.check_config("test_init_dev_mode", config, preconfig,
-                          api=API_PYTHON)
+        self.check_all_configs("test_init_dev_mode", config, preconfig,
+                               api=API_PYTHON)
 
     def test_preinit_parse_argv(self):
         # Pre-initialize implicitly using argv: make sure that -X dev
@@ -807,8 +807,8 @@ def test_preinit_parse_argv(self):
             'warnoptions': ['default'],
             'xoptions': ['dev'],
         }
-        self.check_config("test_preinit_parse_argv", config, preconfig,
-                          api=API_PYTHON)
+        self.check_all_configs("test_preinit_parse_argv", config, preconfig,
+                               api=API_PYTHON)
 
     def test_preinit_dont_parse_argv(self):
         # -X dev must be ignored by isolated preconfiguration
@@ -820,8 +820,8 @@ def test_preinit_dont_parse_argv(self):
                      "-X", "dev", "-X", "utf8", "script.py"],
             'isolated': 0,
         }
-        self.check_config("test_preinit_dont_parse_argv", config, preconfig,
-                          api=API_ISOLATED)
+        self.check_all_configs("test_preinit_dont_parse_argv", config, preconfig,
+                               api=API_ISOLATED)
 
     def test_init_isolated_flag(self):
         config = {
@@ -829,7 +829,7 @@ def test_init_isolated_flag(self):
             'use_environment': 0,
             'user_site_directory': 0,
         }
-        self.check_config("test_init_isolated_flag", config, api=API_PYTHON)
+        self.check_all_configs("test_init_isolated_flag", config, api=API_PYTHON)
 
     def test_preinit_isolated1(self):
         # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set
@@ -838,7 +838,7 @@ def test_preinit_isolated1(self):
             'use_environment': 0,
             'user_site_directory': 0,
         }
-        self.check_config("test_preinit_isolated1", config, api=API_COMPAT)
+        self.check_all_configs("test_preinit_isolated1", config, api=API_COMPAT)
 
     def test_preinit_isolated2(self):
         # _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1
@@ -847,19 +847,19 @@ def test_preinit_isolated2(self):
             'use_environment': 0,
             'user_site_directory': 0,
         }
-        self.check_config("test_preinit_isolated2", config, api=API_COMPAT)
+        self.check_all_configs("test_preinit_isolated2", config, api=API_COMPAT)
 
     def test_preinit_isolated_config(self):
-        self.check_config("test_preinit_isolated_config", api=API_ISOLATED)
+        self.check_all_configs("test_preinit_isolated_config", api=API_ISOLATED)
 
     def test_init_isolated_config(self):
-        self.check_config("test_init_isolated_config", api=API_ISOLATED)
+        self.check_all_configs("test_init_isolated_config", api=API_ISOLATED)
 
     def test_preinit_python_config(self):
-        self.check_config("test_preinit_python_config", api=API_PYTHON)
+        self.check_all_configs("test_preinit_python_config", api=API_PYTHON)
 
     def test_init_python_config(self):
-        self.check_config("test_init_python_config", api=API_PYTHON)
+        self.check_all_configs("test_init_python_config", api=API_PYTHON)
 
     def test_init_dont_configure_locale(self):
         # _PyPreConfig.configure_locale=0
@@ -867,64 +867,64 @@ def test_init_dont_configure_locale(self):
             'configure_locale': 0,
             'coerce_c_locale': 0,
         }
-        self.check_config("test_init_dont_configure_locale", {}, preconfig,
-                          api=API_PYTHON)
+        self.check_all_configs("test_init_dont_configure_locale", {}, preconfig,
+                               api=API_PYTHON)
 
     def test_init_read_set(self):
-        core_config = {
+        config = {
             'program_name': './init_read_set',
             'executable': 'my_executable',
         }
-        self.check_config("test_init_read_set", core_config,
-                          api=API_PYTHON,
-                          add_path="init_read_set_path")
+        self.check_all_configs("test_init_read_set", config,
+                               api=API_PYTHON,
+                               add_path="init_read_set_path")
 
     def test_init_run_main(self):
         code = ('import _testinternalcapi, json; '
                 'print(json.dumps(_testinternalcapi.get_configs()))')
-        core_config = {
+        config = {
             'argv': ['-c', 'arg2'],
             'program_name': './python3',
             'run_command': code + '\n',
             'parse_argv': 1,
         }
-        self.check_config("test_init_run_main", core_config, api=API_PYTHON)
+        self.check_all_configs("test_init_run_main", config, api=API_PYTHON)
 
     def test_init_main(self):
         code = ('import _testinternalcapi, json; '
                 'print(json.dumps(_testinternalcapi.get_configs()))')
-        core_config = {
+        config = {
             'argv': ['-c', 'arg2'],
             'program_name': './python3',
             'run_command': code + '\n',
             'parse_argv': 1,
             '_init_main': 0,
         }
-        self.check_config("test_init_main", core_config,
-                          api=API_PYTHON,
-                          stderr="Run Python code before _Py_InitializeMain")
+        self.check_all_configs("test_init_main", config,
+                               api=API_PYTHON,
+                               stderr="Run Python code before _Py_InitializeMain")
 
     def test_init_parse_argv(self):
-        core_config = {
+        config = {
             'parse_argv': 1,
             'argv': ['-c', 'arg1', '-v', 'arg3'],
             'program_name': './argv0',
             'run_command': 'pass\n',
             'use_environment': 0,
         }
-        self.check_config("test_init_parse_argv", core_config, api=API_PYTHON)
+        self.check_all_configs("test_init_parse_argv", config, api=API_PYTHON)
 
     def test_init_dont_parse_argv(self):
         pre_config = {
             'parse_argv': 0,
         }
-        core_config = {
+        config = {
             'parse_argv': 0,
             'argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'],
             'program_name': './argv0',
         }
-        self.check_config("test_init_dont_parse_argv", core_config, pre_config,
-                          api=API_PYTHON)
+        self.check_all_configs("test_init_dont_parse_argv", config, pre_config,
+                               api=API_PYTHON)
 
 
 class AuditingTests(EmbeddingTestsMixin, unittest.TestCase):
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 8071a94dd6ff..0bf5df4b68e5 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -322,7 +322,7 @@ PYTHON_OBJS=	\
 		Python/ceval.o \
 		Python/codecs.o \
 		Python/compile.o \
-		Python/coreconfig.o \
+		Python/context.o \
 		Python/dynamic_annotations.o \
 		Python/errors.o \
 		Python/frozenmain.o \
@@ -333,8 +333,10 @@ PYTHON_OBJS=	\
 		Python/getplatform.o \
 		Python/getversion.o \
 		Python/graminit.o \
+		Python/hamt.o \
 		Python/import.o \
 		Python/importdl.o \
+		Python/initconfig.o \
 		Python/marshal.o \
 		Python/modsupport.o \
 		Python/mysnprintf.o \
@@ -349,8 +351,6 @@ PYTHON_OBJS=	\
 		Python/pylifecycle.o \
 		Python/pymath.o \
 		Python/pystate.o \
-		Python/context.o \
-		Python/hamt.o \
 		Python/pythonrun.o \
 		Python/pytime.o \
 		Python/bootstrap_hash.o \
@@ -1052,9 +1052,9 @@ PYTHON_HEADERS= \
 		$(srcdir)/Include/Python-ast.h \
 		\
 		$(srcdir)/Include/cpython/abstract.h \
-		$(srcdir)/Include/cpython/coreconfig.h \
 		$(srcdir)/Include/cpython/dictobject.h \
 		$(srcdir)/Include/cpython/fileobject.h \
+		$(srcdir)/Include/cpython/initconfig.h \
 		$(srcdir)/Include/cpython/interpreteridobject.h \
 		$(srcdir)/Include/cpython/object.h \
 		$(srcdir)/Include/cpython/objimpl.h \
@@ -1072,11 +1072,11 @@ PYTHON_HEADERS= \
 		$(srcdir)/Include/internal/pycore_ceval.h \
 		$(srcdir)/Include/internal/pycore_condvar.h \
 		$(srcdir)/Include/internal/pycore_context.h \
-		$(srcdir)/Include/internal/pycore_coreconfig.h \
 		$(srcdir)/Include/internal/pycore_fileutils.h \
 		$(srcdir)/Include/internal/pycore_getopt.h \
 		$(srcdir)/Include/internal/pycore_gil.h \
 		$(srcdir)/Include/internal/pycore_hamt.h \
+		$(srcdir)/Include/internal/pycore_initconfig.h \
 		$(srcdir)/Include/internal/pycore_object.h \
 		$(srcdir)/Include/internal/pycore_pathconfig.h \
 		$(srcdir)/Include/internal/pycore_pyerrors.h \
diff --git a/Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst b/Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst
new file mode 100644
index 000000000000..fc5a48107cfd
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst	
@@ -0,0 +1 @@
+Implement the :pep:`587` "Python Initialization Configuration".
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c
index ba8f0018043f..5c2f019e840b 100644
--- a/Modules/_io/_iomodule.c
+++ b/Modules/_io/_iomodule.c
@@ -377,7 +377,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
     {
         PyObject *RawIO_class = (PyObject *)&PyFileIO_Type;
 #ifdef MS_WINDOWS
-        _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
+        PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config;
         if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') {
             RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type;
             encoding = "utf-8";
diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c
index 6a0d9bec5af3..a5727b8deed3 100644
--- a/Modules/_io/iobase.c
+++ b/Modules/_io/iobase.c
@@ -288,7 +288,7 @@ iobase_finalize(PyObject *self)
            shutdown issues). */
         if (res == NULL) {
 #ifndef Py_DEBUG
-            const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
+            const PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config;
             if (config->dev_mode) {
                 PyErr_WriteUnraisable(self);
             }
diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c
index 3a43ec16850f..3ea77e6934db 100644
--- a/Modules/_testinternalcapi.c
+++ b/Modules/_testinternalcapi.c
@@ -9,7 +9,7 @@
 #define PY_SSIZE_T_CLEAN
 
 #include "Python.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 
 
 static PyObject *
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
index aa466c46ccff..f2b5a503f4ee 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -1,5 +1,5 @@
 #include "Python.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_traceback.h"
 #include "pythread.h"
 #include <signal.h>
@@ -1315,7 +1315,7 @@ faulthandler_init_enable(void)
     return 0;
 }
 
-_PyInitError
+PyStatus
 _PyFaulthandler_Init(int enable)
 {
 #ifdef HAVE_SIGALTSTACK
@@ -1340,17 +1340,17 @@ _PyFaulthandler_Init(int enable)
     thread.cancel_event = PyThread_allocate_lock();
     thread.running = PyThread_allocate_lock();
     if (!thread.cancel_event || !thread.running) {
-        return _Py_INIT_ERR("failed to allocate locks for faulthandler");
+        return _PyStatus_ERR("failed to allocate locks for faulthandler");
     }
     PyThread_acquire_lock(thread.cancel_event, 1);
 #endif
 
     if (enable) {
         if (faulthandler_init_enable() < 0) {
-            return _Py_INIT_ERR("failed to enable faulthandler");
+            return _PyStatus_ERR("failed to enable faulthandler");
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 void _PyFaulthandler_Fini(void)
diff --git a/Modules/getpath.c b/Modules/getpath.c
index 3dcfcef7bd78..5f8073818802 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -1,7 +1,7 @@
 /* Return the initial module search path. */
 
 #include "Python.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "osdefs.h"
 #include "pycore_fileutils.h"
 #include "pycore_pathconfig.h"
@@ -115,10 +115,10 @@ extern "C" {
 
 #define DECODE_LOCALE_ERR(NAME, LEN) \
     ((LEN) == (size_t)-2) \
-     ? _Py_INIT_ERR("cannot decode " NAME) \
-     : _Py_INIT_NO_MEMORY()
+     ? _PyStatus_ERR("cannot decode " NAME) \
+     : _PyStatus_NO_MEMORY()
 
-#define PATHLEN_ERR() _Py_INIT_ERR("path configuration: path too long")
+#define PATHLEN_ERR() _PyStatus_ERR("path configuration: path too long")
 
 typedef struct {
     wchar_t *path_env;                 /* PATH environment variable */
@@ -236,7 +236,7 @@ isdir(wchar_t *filename)
 
 /* Add a path component, by appending stuff to buffer.
    buflen: 'buffer' length in characters including trailing NUL. */
-static _PyInitError
+static PyStatus
 joinpath(wchar_t *buffer, const wchar_t *stuff, size_t buflen)
 {
     size_t n, k;
@@ -261,7 +261,7 @@ joinpath(wchar_t *buffer, const wchar_t *stuff, size_t buflen)
     wcsncpy(buffer+n, stuff, k);
     buffer[n+k] = '\0';
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -280,7 +280,7 @@ safe_wcscpy(wchar_t *dst, const wchar_t *src, size_t n)
 
 /* copy_absolute requires that path be allocated at least
    'pathlen' characters (including trailing NUL). */
-static _PyInitError
+static PyStatus
 copy_absolute(wchar_t *path, const wchar_t *p, size_t pathlen)
 {
     if (p[0] == SEP) {
@@ -294,38 +294,38 @@ copy_absolute(wchar_t *path, const wchar_t *p, size_t pathlen)
             if (safe_wcscpy(path, p, pathlen) < 0) {
                 return PATHLEN_ERR();
             }
-            return _Py_INIT_OK();
+            return _PyStatus_OK();
         }
         if (p[0] == '.' && p[1] == SEP) {
             p += 2;
         }
-        _PyInitError err = joinpath(path, p, pathlen);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        PyStatus status = joinpath(path, p, pathlen);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
 /* path_len: path length in characters including trailing NUL */
-static _PyInitError
+static PyStatus
 absolutize(wchar_t *path, size_t path_len)
 {
     if (path[0] == SEP) {
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     wchar_t abs_path[MAXPATHLEN+1];
-    _PyInitError err = copy_absolute(abs_path, path, Py_ARRAY_LENGTH(abs_path));
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = copy_absolute(abs_path, path, Py_ARRAY_LENGTH(abs_path));
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if (safe_wcscpy(path, abs_path, path_len) < 0) {
         return PATHLEN_ERR();
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -335,14 +335,14 @@ absolutize(wchar_t *path, size_t path_len)
 #endif
 
 /* pathlen: 'path' length in characters including trailing NUL */
-static _PyInitError
+static PyStatus
 add_exe_suffix(wchar_t *progpath, size_t progpathlen)
 {
     /* Check for already have an executable suffix */
     size_t n = wcslen(progpath);
     size_t s = wcslen(EXE_SUFFIX);
     if (wcsncasecmp(EXE_SUFFIX, progpath + n - s, s) == 0) {
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     if (n + s >= progpathlen) {
@@ -356,7 +356,7 @@ add_exe_suffix(wchar_t *progpath, size_t progpathlen)
         progpath[n] = '\0';
     }
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 #endif
 
@@ -364,43 +364,43 @@ add_exe_suffix(wchar_t *progpath, size_t progpathlen)
 /* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
    bytes long.
 */
-static _PyInitError
-search_for_prefix(const _PyCoreConfig *core_config, PyCalculatePath *calculate,
+static PyStatus
+search_for_prefix(const PyConfig *config, PyCalculatePath *calculate,
                   wchar_t *prefix, size_t prefix_len,
                   int *found)
 {
-    _PyInitError err;
+    PyStatus status;
     size_t n;
     wchar_t *vpath;
 
     /* If PYTHONHOME is set, we believe it unconditionally */
-    if (core_config->home) {
-        if (safe_wcscpy(prefix, core_config->home, prefix_len) < 0) {
+    if (config->home) {
+        if (safe_wcscpy(prefix, config->home, prefix_len) < 0) {
             return PATHLEN_ERR();
         }
         wchar_t *delim = wcschr(prefix, DELIM);
         if (delim) {
             *delim = L'\0';
         }
-        err = joinpath(prefix, calculate->lib_python, prefix_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(prefix, calculate->lib_python, prefix_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
-        err = joinpath(prefix, LANDMARK, prefix_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(prefix, LANDMARK, prefix_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
         *found = 1;
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     /* Check to see if argv[0] is in the build directory */
     if (safe_wcscpy(prefix, calculate->argv0_path, prefix_len) < 0) {
         return PATHLEN_ERR();
     }
-    err = joinpath(prefix, L"Modules/Setup.local", prefix_len);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = joinpath(prefix, L"Modules/Setup.local", prefix_len);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if (isfile(prefix)) {
@@ -410,48 +410,48 @@ search_for_prefix(const _PyCoreConfig *core_config, PyCalculatePath *calculate,
             if (safe_wcscpy(prefix, calculate->argv0_path, prefix_len) < 0) {
                 return PATHLEN_ERR();
             }
-            err = joinpath(prefix, vpath, prefix_len);
+            status = joinpath(prefix, vpath, prefix_len);
             PyMem_RawFree(vpath);
-            if (_Py_INIT_FAILED(err)) {
-                return err;
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
 
-            err = joinpath(prefix, L"Lib", prefix_len);
-            if (_Py_INIT_FAILED(err)) {
-                return err;
+            status = joinpath(prefix, L"Lib", prefix_len);
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
-            err = joinpath(prefix, LANDMARK, prefix_len);
-            if (_Py_INIT_FAILED(err)) {
-                return err;
+            status = joinpath(prefix, LANDMARK, prefix_len);
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
 
             if (ismodule(prefix, prefix_len)) {
                 *found = -1;
-                return _Py_INIT_OK();
+                return _PyStatus_OK();
             }
         }
     }
 
     /* Search from argv0_path, until root is found */
-    err = copy_absolute(prefix, calculate->argv0_path, prefix_len);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = copy_absolute(prefix, calculate->argv0_path, prefix_len);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     do {
         n = wcslen(prefix);
-        err = joinpath(prefix, calculate->lib_python, prefix_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(prefix, calculate->lib_python, prefix_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
-        err = joinpath(prefix, LANDMARK, prefix_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(prefix, LANDMARK, prefix_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
         if (ismodule(prefix, prefix_len)) {
             *found = 1;
-            return _Py_INIT_OK();
+            return _PyStatus_OK();
         }
         prefix[n] = L'\0';
         reduce(prefix);
@@ -461,59 +461,59 @@ search_for_prefix(const _PyCoreConfig *core_config, PyCalculatePath *calculate,
     if (safe_wcscpy(prefix, calculate->prefix, prefix_len) < 0) {
         return PATHLEN_ERR();
     }
-    err = joinpath(prefix, calculate->lib_python, prefix_len);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = joinpath(prefix, calculate->lib_python, prefix_len);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-    err = joinpath(prefix, LANDMARK, prefix_len);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = joinpath(prefix, LANDMARK, prefix_len);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if (ismodule(prefix, prefix_len)) {
         *found = 1;
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     /* Fail */
     *found = 0;
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-calculate_prefix(const _PyCoreConfig *core_config,
+static PyStatus
+calculate_prefix(const PyConfig *config,
                  PyCalculatePath *calculate, wchar_t *prefix, size_t prefix_len)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    err = search_for_prefix(core_config, calculate, prefix, prefix_len,
+    status = search_for_prefix(config, calculate, prefix, prefix_len,
                             &calculate->prefix_found);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if (!calculate->prefix_found) {
-        if (core_config->pathconfig_warnings) {
+        if (config->pathconfig_warnings) {
             fprintf(stderr,
                 "Could not find platform independent libraries <prefix>\n");
         }
         if (safe_wcscpy(prefix, calculate->prefix, prefix_len) < 0) {
             return PATHLEN_ERR();
         }
-        err = joinpath(prefix, calculate->lib_python, prefix_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(prefix, calculate->lib_python, prefix_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
     else {
         reduce(prefix);
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
+static PyStatus
 calculate_reduce_prefix(PyCalculatePath *calculate,
                         wchar_t *prefix, size_t prefix_len)
 {
@@ -536,45 +536,45 @@ calculate_reduce_prefix(PyCalculatePath *calculate,
             return PATHLEN_ERR();
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
 /* search_for_exec_prefix requires that argv0_path be no more than
    MAXPATHLEN bytes long.
 */
-static _PyInitError
-search_for_exec_prefix(const _PyCoreConfig *core_config,
+static PyStatus
+search_for_exec_prefix(const PyConfig *config,
                        PyCalculatePath *calculate,
                        wchar_t *exec_prefix, size_t exec_prefix_len,
                        int *found)
 {
-    _PyInitError err;
+    PyStatus status;
     size_t n;
 
     /* If PYTHONHOME is set, we believe it unconditionally */
-    if (core_config->home) {
-        wchar_t *delim = wcschr(core_config->home, DELIM);
+    if (config->home) {
+        wchar_t *delim = wcschr(config->home, DELIM);
         if (delim) {
             if (safe_wcscpy(exec_prefix, delim+1, exec_prefix_len) < 0) {
                 return PATHLEN_ERR();
             }
         }
         else {
-            if (safe_wcscpy(exec_prefix, core_config->home, exec_prefix_len) < 0) {
+            if (safe_wcscpy(exec_prefix, config->home, exec_prefix_len) < 0) {
                 return PATHLEN_ERR();
             }
         }
-        err = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
-        err = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
         *found = 1;
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
@@ -583,9 +583,9 @@ search_for_exec_prefix(const _PyCoreConfig *core_config,
     if (safe_wcscpy(exec_prefix, calculate->argv0_path, exec_prefix_len) < 0) {
         return PATHLEN_ERR();
     }
-    err = joinpath(exec_prefix, L"pybuilddir.txt", exec_prefix_len);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = joinpath(exec_prefix, L"pybuilddir.txt", exec_prefix_len);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if (isfile(exec_prefix)) {
@@ -609,36 +609,36 @@ search_for_exec_prefix(const _PyCoreConfig *core_config,
             if (safe_wcscpy(exec_prefix, calculate->argv0_path, exec_prefix_len) < 0) {
                 return PATHLEN_ERR();
             }
-            err = joinpath(exec_prefix, pybuilddir, exec_prefix_len);
+            status = joinpath(exec_prefix, pybuilddir, exec_prefix_len);
             PyMem_RawFree(pybuilddir );
-            if (_Py_INIT_FAILED(err)) {
-                return err;
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
 
             *found = -1;
-            return _Py_INIT_OK();
+            return _PyStatus_OK();
         }
     }
 
     /* Search from argv0_path, until root is found */
-    err = copy_absolute(exec_prefix, calculate->argv0_path, exec_prefix_len);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = copy_absolute(exec_prefix, calculate->argv0_path, exec_prefix_len);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     do {
         n = wcslen(exec_prefix);
-        err = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
-        err = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
         if (isdir(exec_prefix)) {
             *found = 1;
-            return _Py_INIT_OK();
+            return _PyStatus_OK();
         }
         exec_prefix[n] = L'\0';
         reduce(exec_prefix);
@@ -648,58 +648,58 @@ search_for_exec_prefix(const _PyCoreConfig *core_config,
     if (safe_wcscpy(exec_prefix, calculate->exec_prefix, exec_prefix_len) < 0) {
         return PATHLEN_ERR();
     }
-    err = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-    err = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
     if (isdir(exec_prefix)) {
         *found = 1;
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     /* Fail */
     *found = 0;
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-calculate_exec_prefix(const _PyCoreConfig *core_config,
+static PyStatus
+calculate_exec_prefix(const PyConfig *config,
                       PyCalculatePath *calculate,
                       wchar_t *exec_prefix, size_t exec_prefix_len)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    err = search_for_exec_prefix(core_config, calculate,
+    status = search_for_exec_prefix(config, calculate,
                                  exec_prefix, exec_prefix_len,
                                  &calculate->exec_prefix_found);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if (!calculate->exec_prefix_found) {
-        if (core_config->pathconfig_warnings) {
+        if (config->pathconfig_warnings) {
             fprintf(stderr,
                 "Could not find platform dependent libraries <exec_prefix>\n");
         }
         if (safe_wcscpy(exec_prefix, calculate->exec_prefix, exec_prefix_len) < 0) {
             return PATHLEN_ERR();
         }
-        err = joinpath(exec_prefix, L"lib/lib-dynload", exec_prefix_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(exec_prefix, L"lib/lib-dynload", exec_prefix_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
     /* If we found EXEC_PREFIX do *not* reduce it!  (Yet.) */
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
+static PyStatus
 calculate_reduce_exec_prefix(PyCalculatePath *calculate,
                              wchar_t *exec_prefix, size_t exec_prefix_len)
 {
@@ -716,15 +716,15 @@ calculate_reduce_exec_prefix(PyCalculatePath *calculate,
             return PATHLEN_ERR();
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-calculate_program_full_path(const _PyCoreConfig *core_config,
-                            PyCalculatePath *calculate, _PyPathConfig *config)
+static PyStatus
+calculate_program_full_path(const PyConfig *config,
+                            PyCalculatePath *calculate, _PyPathConfig *pathconfig)
 {
-    _PyInitError err;
+    PyStatus status;
     wchar_t program_full_path[MAXPATHLEN + 1];
     const size_t program_full_path_len = Py_ARRAY_LENGTH(program_full_path);
     memset(program_full_path, 0, sizeof(program_full_path));
@@ -743,8 +743,8 @@ calculate_program_full_path(const _PyCoreConfig *core_config,
      * other way to find a directory to start the search from.  If
      * $PATH isn't exported, you lose.
      */
-    if (wcschr(core_config->program_name, SEP)) {
-        if (safe_wcscpy(program_full_path, core_config->program_name,
+    if (wcschr(config->program_name, SEP)) {
+        if (safe_wcscpy(program_full_path, config->program_name,
                         program_full_path_len) < 0) {
             return PATHLEN_ERR();
         }
@@ -795,10 +795,10 @@ calculate_program_full_path(const _PyCoreConfig *core_config,
                 }
             }
 
-            err = joinpath(program_full_path, core_config->program_name,
+            status = joinpath(program_full_path, config->program_name,
                             program_full_path_len);
-            if (_Py_INIT_FAILED(err)) {
-                return err;
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
 
             if (isxfile(program_full_path)) {
@@ -816,9 +816,9 @@ calculate_program_full_path(const _PyCoreConfig *core_config,
         program_full_path[0] = '\0';
     }
     if (program_full_path[0] != SEP && program_full_path[0] != '\0') {
-        err = absolutize(program_full_path, program_full_path_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = absolutize(program_full_path, program_full_path_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 #if defined(__CYGWIN__) || defined(__MINGW32__)
@@ -828,22 +828,22 @@ calculate_program_full_path(const _PyCoreConfig *core_config,
      * path (bpo-28441).
      */
     if (program_full_path[0] != '\0') {
-        err = add_exe_suffix(program_full_path, program_full_path_len);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = add_exe_suffix(program_full_path, program_full_path_len);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 #endif
 
-    config->program_full_path = _PyMem_RawWcsdup(program_full_path);
-    if (config->program_full_path == NULL) {
-        return _Py_INIT_NO_MEMORY();
+    pathconfig->program_full_path = _PyMem_RawWcsdup(program_full_path);
+    if (pathconfig->program_full_path == NULL) {
+        return _PyStatus_NO_MEMORY();
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
+static PyStatus
 calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path)
 {
     const size_t argv0_path_len = Py_ARRAY_LENGTH(calculate->argv0_path);
@@ -871,7 +871,7 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat
         ** be running the interpreter in the build directory, so we use the
         ** build-directory-specific logic to find Lib and such.
         */
-        _PyInitError err;
+        PyStatus status;
         size_t len;
         wchar_t* wbuf = Py_DecodeLocale(modPath, &len);
         if (wbuf == NULL) {
@@ -882,15 +882,15 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat
             return PATHLEN_ERR();
         }
         reduce(calculate->argv0_path);
-        err = joinpath(calculate->argv0_path, calculate->lib_python, argv0_path_len);
-        if (_Py_INIT_FAILED(err)) {
+        status = joinpath(calculate->argv0_path, calculate->lib_python, argv0_path_len);
+        if (_PyStatus_EXCEPTION(status)) {
             PyMem_RawFree(wbuf);
-            return err;
+            return status;
         }
-        err = joinpath(calculate->argv0_path, LANDMARK, argv0_path_len);
-        if (_Py_INIT_FAILED(err)) {
+        status = joinpath(calculate->argv0_path, LANDMARK, argv0_path_len);
+        if (_PyStatus_EXCEPTION(status)) {
             PyMem_RawFree(wbuf);
-            return err;
+            return status;
         }
         if (!ismodule(calculate->argv0_path,
                       Py_ARRAY_LENGTH(calculate->argv0_path))) {
@@ -925,11 +925,11 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat
         }
         else {
             /* Interpret relative to program_full_path */
-            _PyInitError err;
+            PyStatus status;
             reduce(calculate->argv0_path);
-            err = joinpath(calculate->argv0_path, tmpbuffer, argv0_path_len);
-            if (_Py_INIT_FAILED(err)) {
-                return err;
+            status = joinpath(calculate->argv0_path, tmpbuffer, argv0_path_len);
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
         }
         linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, buflen);
@@ -939,7 +939,7 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat
     reduce(calculate->argv0_path);
     /* At this point, argv0_path is guaranteed to be less than
        MAXPATHLEN bytes long. */
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -947,10 +947,10 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat
    executable's directory and then in the parent directory.
    If found, open it for use when searching for prefixes.
 */
-static _PyInitError
+static PyStatus
 calculate_read_pyenv(PyCalculatePath *calculate)
 {
-    _PyInitError err;
+    PyStatus status;
     wchar_t tmpbuffer[MAXPATHLEN+1];
     const size_t buflen = Py_ARRAY_LENGTH(tmpbuffer);
     wchar_t *env_cfg = L"pyvenv.cfg";
@@ -960,9 +960,9 @@ calculate_read_pyenv(PyCalculatePath *calculate)
         return PATHLEN_ERR();
     }
 
-    err = joinpath(tmpbuffer, env_cfg, buflen);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = joinpath(tmpbuffer, env_cfg, buflen);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
     env_file = _Py_wfopen(tmpbuffer, L"r");
     if (env_file == NULL) {
@@ -970,9 +970,9 @@ calculate_read_pyenv(PyCalculatePath *calculate)
 
         reduce(tmpbuffer);
         reduce(tmpbuffer);
-        err = joinpath(tmpbuffer, env_cfg, buflen);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = joinpath(tmpbuffer, env_cfg, buflen);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
         env_file = _Py_wfopen(tmpbuffer, L"r");
@@ -982,7 +982,7 @@ calculate_read_pyenv(PyCalculatePath *calculate)
     }
 
     if (env_file == NULL) {
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     /* Look for a 'home' variable and set argv0_path to it, if found */
@@ -993,14 +993,14 @@ calculate_read_pyenv(PyCalculatePath *calculate)
         }
     }
     fclose(env_file);
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
+static PyStatus
 calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
 {
-    _PyInitError err;
+    PyStatus status;
     const size_t zip_path_len = Py_ARRAY_LENGTH(calculate->zip_path);
     if (safe_wcscpy(calculate->zip_path, prefix, zip_path_len) < 0) {
         return PATHLEN_ERR();
@@ -1016,29 +1016,29 @@ calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
             return PATHLEN_ERR();
         }
     }
-    err = joinpath(calculate->zip_path, L"lib/python00.zip", zip_path_len);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = joinpath(calculate->zip_path, L"lib/python00.zip", zip_path_len);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     /* Replace "00" with version */
     size_t bufsz = wcslen(calculate->zip_path);
     calculate->zip_path[bufsz - 6] = VERSION[0];
     calculate->zip_path[bufsz - 5] = VERSION[2];
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-calculate_module_search_path(const _PyCoreConfig *core_config,
+static PyStatus
+calculate_module_search_path(const PyConfig *config,
                              PyCalculatePath *calculate,
                              const wchar_t *prefix, const wchar_t *exec_prefix,
-                             _PyPathConfig *config)
+                             _PyPathConfig *pathconfig)
 {
     /* Calculate size of return buffer */
     size_t bufsz = 0;
-    if (core_config->module_search_path_env != NULL) {
-        bufsz += wcslen(core_config->module_search_path_env) + 1;
+    if (config->pythonpath_env != NULL) {
+        bufsz += wcslen(config->pythonpath_env) + 1;
     }
 
     wchar_t *defpath = calculate->pythonpath;
@@ -1067,13 +1067,13 @@ calculate_module_search_path(const _PyCoreConfig *core_config,
     /* Allocate the buffer */
     wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
     if (buf == NULL) {
-        return _Py_INIT_NO_MEMORY();
+        return _PyStatus_NO_MEMORY();
     }
     buf[0] = '\0';
 
     /* Run-time value of $PYTHONPATH goes first */
-    if (core_config->module_search_path_env) {
-        wcscpy(buf, core_config->module_search_path_env);
+    if (config->pythonpath_env) {
+        wcscpy(buf, config->pythonpath_env);
         wcscat(buf, delimiter);
     }
 
@@ -1115,14 +1115,14 @@ calculate_module_search_path(const _PyCoreConfig *core_config,
     /* Finally, on goes the directory for dynamic-load modules */
     wcscat(buf, exec_prefix);
 
-    config->module_search_path = buf;
-    return _Py_INIT_OK();
+    pathconfig->module_search_path = buf;
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
+static PyStatus
 calculate_init(PyCalculatePath *calculate,
-               const _PyCoreConfig *core_config)
+               const PyConfig *config)
 {
     size_t len;
     const char *path = getenv("PATH");
@@ -1149,7 +1149,7 @@ calculate_init(PyCalculatePath *calculate,
     if (!calculate->lib_python) {
         return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -1164,108 +1164,108 @@ calculate_free(PyCalculatePath *calculate)
 }
 
 
-static _PyInitError
-calculate_path_impl(const _PyCoreConfig *core_config,
-                    PyCalculatePath *calculate, _PyPathConfig *config)
+static PyStatus
+calculate_path_impl(const PyConfig *config,
+                    PyCalculatePath *calculate, _PyPathConfig *pathconfig)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    err = calculate_program_full_path(core_config, calculate, config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = calculate_program_full_path(config, calculate, pathconfig);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = calculate_argv0_path(calculate, config->program_full_path);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = calculate_argv0_path(calculate, pathconfig->program_full_path);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = calculate_read_pyenv(calculate);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = calculate_read_pyenv(calculate);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     wchar_t prefix[MAXPATHLEN+1];
     memset(prefix, 0, sizeof(prefix));
-    err = calculate_prefix(core_config, calculate,
+    status = calculate_prefix(config, calculate,
                            prefix, Py_ARRAY_LENGTH(prefix));
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = calculate_zip_path(calculate, prefix);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = calculate_zip_path(calculate, prefix);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     wchar_t exec_prefix[MAXPATHLEN+1];
     memset(exec_prefix, 0, sizeof(exec_prefix));
-    err = calculate_exec_prefix(core_config, calculate,
+    status = calculate_exec_prefix(config, calculate,
                                 exec_prefix, Py_ARRAY_LENGTH(exec_prefix));
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
-        core_config->pathconfig_warnings)
+        config->pathconfig_warnings)
     {
         fprintf(stderr,
                 "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
     }
 
-    err = calculate_module_search_path(core_config, calculate,
-                                       prefix, exec_prefix, config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = calculate_module_search_path(config, calculate,
+                                       prefix, exec_prefix, pathconfig);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = calculate_reduce_prefix(calculate, prefix, Py_ARRAY_LENGTH(prefix));
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = calculate_reduce_prefix(calculate, prefix, Py_ARRAY_LENGTH(prefix));
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    config->prefix = _PyMem_RawWcsdup(prefix);
-    if (config->prefix == NULL) {
-        return _Py_INIT_NO_MEMORY();
+    pathconfig->prefix = _PyMem_RawWcsdup(prefix);
+    if (pathconfig->prefix == NULL) {
+        return _PyStatus_NO_MEMORY();
     }
 
-    err = calculate_reduce_exec_prefix(calculate,
+    status = calculate_reduce_exec_prefix(calculate,
                                        exec_prefix, Py_ARRAY_LENGTH(exec_prefix));
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    config->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
-    if (config->exec_prefix == NULL) {
-        return _Py_INIT_NO_MEMORY();
+    pathconfig->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
+    if (pathconfig->exec_prefix == NULL) {
+        return _PyStatus_NO_MEMORY();
     }
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-_PyInitError
-_PyPathConfig_Calculate_impl(_PyPathConfig *config, const _PyCoreConfig *core_config)
+PyStatus
+_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
 {
-    _PyInitError err;
+    PyStatus status;
     PyCalculatePath calculate;
     memset(&calculate, 0, sizeof(calculate));
 
-    err = calculate_init(&calculate, core_config);
-    if (_Py_INIT_FAILED(err)) {
+    status = calculate_init(&calculate, config);
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
-    err = calculate_path_impl(core_config, &calculate, config);
-    if (_Py_INIT_FAILED(err)) {
+    status = calculate_path_impl(config, &calculate, pathconfig);
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
-    err = _Py_INIT_OK();
+    status = _PyStatus_OK();
 
 done:
     calculate_free(&calculate);
-    return err;
+    return status;
 }
 
 #ifdef __cplusplus
diff --git a/Modules/main.c b/Modules/main.c
index 08fb0e0417d0..6b9406f78666 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -1,7 +1,7 @@
 /* Python interpreter main program */
 
 #include "Python.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_pylifecycle.h"
 #include "pycore_pymem.h"
 #include "pycore_pystate.h"
@@ -33,14 +33,14 @@ extern "C" {
 
 /* --- pymain_init() ---------------------------------------------- */
 
-static _PyInitError
+static PyStatus
 pymain_init(const _PyArgv *args)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    err = _PyRuntime_Initialize();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyRuntime_Initialize();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     /* 754 requires that FP exceptions run in "no stop" mode by default,
@@ -52,29 +52,36 @@ pymain_init(const _PyArgv *args)
     fedisableexcept(FE_OVERFLOW);
 #endif
 
-    _PyPreConfig preconfig;
-    _PyPreConfig_InitPythonConfig(&preconfig);
-    err = _Py_PreInitializeFromPyArgv(&preconfig, args);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyPreConfig preconfig;
+    PyPreConfig_InitPythonConfig(&preconfig);
+    status = _Py_PreInitializeFromPyArgv(&preconfig, args);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyConfig config;
+    status = PyConfig_InitPythonConfig(&config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     /* pass NULL as the config: config is read from command line arguments,
        environment variables, configuration files */
     if (args->use_bytes_argv) {
-        return _Py_InitializeFromArgs(&config,
-                                      args->argc, args->bytes_argv);
+        status = PyConfig_SetBytesArgv(&config, args->argc, args->bytes_argv);
     }
     else {
-        return _Py_InitializeFromWideArgs(&config,
-                                          args->argc, args->wchar_argv);
+        status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv);
     }
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
+
+    status = Py_InitializeFromConfig(&config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
+    return _PyStatus_OK();
 }
 
 
@@ -82,13 +89,17 @@ pymain_init(const _PyArgv *args)
 
 /* Non-zero if filename, command (-c) or module (-m) is set
    on the command line */
-#define RUN_CODE(config) \
-    (config->run_command != NULL || config->run_filename != NULL \
-     || config->run_module != NULL)
+static inline int config_run_code(const PyConfig *config)
+{
+    return (config->run_command != NULL
+            || config->run_filename != NULL
+            || config->run_module != NULL);
+}
+
 
 /* Return non-zero is stdin is a TTY or if -i command line option is used */
 static int
-stdin_is_interactive(const _PyCoreConfig *config)
+stdin_is_interactive(const PyConfig *config)
 {
     return (isatty(fileno(stdin)) || config->interactive);
 }
@@ -181,13 +192,13 @@ pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0)
 
 
 static void
-pymain_header(const _PyCoreConfig *config)
+pymain_header(const PyConfig *config)
 {
     if (config->quiet) {
         return;
     }
 
-    if (!config->verbose && (RUN_CODE(config) || !stdin_is_interactive(config))) {
+    if (!config->verbose && (config_run_code(config) || !stdin_is_interactive(config))) {
         return;
     }
 
@@ -199,12 +210,12 @@ pymain_header(const _PyCoreConfig *config)
 
 
 static void
-pymain_import_readline(const _PyCoreConfig *config)
+pymain_import_readline(const PyConfig *config)
 {
     if (config->isolated) {
         return;
     }
-    if (!config->inspect && RUN_CODE(config)) {
+    if (!config->inspect && config_run_code(config)) {
         return;
     }
     if (!isatty(fileno(stdin))) {
@@ -293,7 +304,7 @@ pymain_run_module(const wchar_t *modname, int set_argv0)
 
 
 static int
-pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)
+pymain_run_file(PyConfig *config, PyCompilerFlags *cf)
 {
     const wchar_t *filename = config->run_filename;
     FILE *fp = _Py_wfopen(filename, L"rb");
@@ -362,7 +373,7 @@ pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)
 
 
 static int
-pymain_run_startup(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode)
+pymain_run_startup(PyConfig *config, PyCompilerFlags *cf, int *exitcode)
 {
     const char *startup = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP");
     if (startup == NULL) {
@@ -421,7 +432,7 @@ pymain_run_interactive_hook(int *exitcode)
 
 
 static int
-pymain_run_stdin(_PyCoreConfig *config, PyCompilerFlags *cf)
+pymain_run_stdin(PyConfig *config, PyCompilerFlags *cf)
 {
     if (stdin_is_interactive(config)) {
         config->inspect = 0;
@@ -448,7 +459,7 @@ pymain_run_stdin(_PyCoreConfig *config, PyCompilerFlags *cf)
 
 
 static void
-pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode)
+pymain_repl(PyConfig *config, PyCompilerFlags *cf, int *exitcode)
 {
     /* Check this environment variable at the end, to give programs the
        opportunity to set it from Python. */
@@ -457,7 +468,7 @@ pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode)
         Py_InspectFlag = 1;
     }
 
-    if (!(config->inspect && stdin_is_interactive(config) && RUN_CODE(config))) {
+    if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) {
         return;
     }
 
@@ -477,7 +488,7 @@ pymain_run_python(int *exitcode)
 {
     PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
     /* pymain_run_stdin() modify the config */
-    _PyCoreConfig *config = &interp->core_config;
+    PyConfig *config = &interp->config;
 
     PyObject *main_importer_path = NULL;
     if (config->run_filename != NULL) {
@@ -590,20 +601,20 @@ exit_sigint(void)
 
 
 static void _Py_NO_RETURN
-pymain_exit_error(_PyInitError err)
+pymain_exit_error(PyStatus status)
 {
-    if (_Py_INIT_IS_EXIT(err)) {
+    if (_PyStatus_IS_EXIT(status)) {
         /* If it's an error rather than a regular exit, leave Python runtime
-           alive: _Py_ExitInitError() uses the current exception and use
+           alive: Py_ExitStatusException() uses the current exception and use
            sys.stdout in this case. */
         pymain_free();
     }
-    _Py_ExitInitError(err);
+    Py_ExitStatusException(status);
 }
 
 
 int
-_Py_RunMain(void)
+Py_RunMain(void)
 {
     int exitcode = 0;
 
@@ -628,16 +639,16 @@ _Py_RunMain(void)
 static int
 pymain_main(_PyArgv *args)
 {
-    _PyInitError err = pymain_init(args);
-    if (_Py_INIT_IS_EXIT(err)) {
+    PyStatus status = pymain_init(args);
+    if (_PyStatus_IS_EXIT(status)) {
         pymain_free();
-        return err.exitcode;
+        return status.exitcode;
     }
-    if (_Py_INIT_FAILED(err)) {
-        pymain_exit_error(err);
+    if (_PyStatus_EXCEPTION(status)) {
+        pymain_exit_error(status);
     }
 
-    return _Py_RunMain();
+    return Py_RunMain();
 }
 
 
@@ -654,7 +665,7 @@ Py_Main(int argc, wchar_t **argv)
 
 
 int
-_Py_UnixMain(int argc, char **argv)
+Py_BytesMain(int argc, char **argv)
 {
     _PyArgv args = {
         .argc = argc,
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 8d5ba540120f..c7c28312b005 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -999,7 +999,7 @@ bytearray_repr(PyByteArrayObject *self)
 static PyObject *
 bytearray_str(PyObject *op)
 {
-    _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
+    PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config;
     if (config->bytes_warning) {
         if (PyErr_WarnEx(PyExc_BytesWarning,
                          "str() on a bytearray instance", 1)) {
@@ -1025,7 +1025,7 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op)
     if (rc < 0)
         return NULL;
     if (rc) {
-        _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
+        PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config;
         if (config->bytes_warning && (op == Py_EQ || op == Py_NE)) {
             if (PyErr_WarnEx(PyExc_BytesWarning,
                             "Comparison between bytearray and string", 1))
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 41453b2d14e9..0a3ed8691a22 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -1421,7 +1421,7 @@ bytes_repr(PyObject *op)
 static PyObject *
 bytes_str(PyObject *op)
 {
-    _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
+    PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config;
     if (config->bytes_warning) {
         if (PyErr_WarnEx(PyExc_BytesWarning,
                          "str() on a bytes instance", 1)) {
@@ -1579,7 +1579,7 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
 
     /* Make sure both arguments are strings. */
     if (!(PyBytes_Check(a) && PyBytes_Check(b))) {
-        _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
+        PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config;
         if (config->bytes_warning && (op == Py_EQ || op == Py_NE)) {
             rc = PyObject_IsInstance((PyObject*)a,
                                      (PyObject*)&PyUnicode_Type);
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 4dad0b24cee8..8456a8f18286 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -6,7 +6,7 @@
 
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_object.h"
 #include "pycore_pymem.h"
 #include "pycore_pystate.h"
@@ -2499,13 +2499,13 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning,
 #endif
 #endif /* MS_WINDOWS */
 
-_PyInitError
+PyStatus
 _PyExc_Init(void)
 {
 #define PRE_INIT(TYPE) \
     if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
         if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \
-            return _Py_INIT_ERR("exceptions bootstrapping error."); \
+            return _PyStatus_ERR("exceptions bootstrapping error."); \
         } \
         Py_INCREF(PyExc_ ## TYPE); \
     }
@@ -2515,7 +2515,7 @@ _PyExc_Init(void)
         PyObject *_code = PyLong_FromLong(CODE); \
         assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
         if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) \
-            return _Py_INIT_ERR("errmap insertion problem."); \
+            return _PyStatus_ERR("errmap insertion problem."); \
         Py_DECREF(_code); \
     } while (0)
 
@@ -2589,14 +2589,14 @@ _PyExc_Init(void)
     PRE_INIT(TimeoutError);
 
     if (preallocate_memerrors() < 0) {
-        return _Py_INIT_ERR("Could not preallocate MemoryError object");
+        return _PyStatus_ERR("Could not preallocate MemoryError object");
     }
 
     /* Add exceptions to errnomap */
     if (!errnomap) {
         errnomap = PyDict_New();
         if (!errnomap) {
-            return _Py_INIT_ERR("Cannot allocate map from errnos to OSError subclasses");
+            return _PyStatus_ERR("Cannot allocate map from errnos to OSError subclasses");
         }
     }
 
@@ -2622,7 +2622,7 @@ _PyExc_Init(void)
     ADD_ERRNO(ProcessLookupError, ESRCH);
     ADD_ERRNO(TimeoutError, ETIMEDOUT);
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 
 #undef PRE_INIT
 #undef ADD_ERRNO
@@ -2630,12 +2630,12 @@ _PyExc_Init(void)
 
 
 /* Add exception types to the builtins module */
-_PyInitError
+PyStatus
 _PyBuiltins_AddExceptions(PyObject *bltinmod)
 {
 #define POST_INIT(TYPE) \
     if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \
-        return _Py_INIT_ERR("Module dictionary insertion problem."); \
+        return _PyStatus_ERR("Module dictionary insertion problem."); \
     }
 
 #define INIT_ALIAS(NAME, TYPE) \
@@ -2644,7 +2644,7 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod)
         Py_XDECREF(PyExc_ ## NAME); \
         PyExc_ ## NAME = PyExc_ ## TYPE; \
         if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) { \
-            return _Py_INIT_ERR("Module dictionary insertion problem."); \
+            return _PyStatus_ERR("Module dictionary insertion problem."); \
         } \
     } while (0)
 
@@ -2652,7 +2652,7 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod)
 
     bdict = PyModule_GetDict(bltinmod);
     if (bdict == NULL) {
-        return _Py_INIT_ERR("exceptions bootstrapping error.");
+        return _PyStatus_ERR("exceptions bootstrapping error.");
     }
 
     POST_INIT(BaseException);
@@ -2729,7 +2729,7 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod)
     POST_INIT(ProcessLookupError);
     POST_INIT(TimeoutError);
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 
 #undef POST_INIT
 #undef INIT_ALIAS
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 3185957453d7..b210c005da13 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -104,7 +104,7 @@ static void
 show_alloc(void)
 {
     PyInterpreterState *interp = _PyInterpreterState_Get();
-    if (!interp->core_config.show_alloc_count) {
+    if (!interp->config.show_alloc_count) {
         return;
     }
 
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index e570107cedfb..20e7d44ab5e1 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -590,7 +590,7 @@ _PyModule_ClearDict(PyObject *d)
     Py_ssize_t pos;
     PyObject *key, *value;
 
-    int verbose = _PyInterpreterState_GET_UNSAFE()->core_config.verbose;
+    int verbose = _PyInterpreterState_GET_UNSAFE()->config.verbose;
 
     /* First, clear only names starting with a single underscore */
     pos = 0;
@@ -677,7 +677,7 @@ module___init___impl(PyModuleObject *self, PyObject *name, PyObject *doc)
 static void
 module_dealloc(PyModuleObject *m)
 {
-    int verbose = _PyInterpreterState_GET_UNSAFE()->core_config.verbose;
+    int verbose = _PyInterpreterState_GET_UNSAFE()->config.verbose;
 
     PyObject_GC_UnTrack(m);
     if (verbose && m->md_name) {
diff --git a/Objects/object.c b/Objects/object.c
index 6d79165683e1..270716f397c9 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2,7 +2,7 @@
 /* Generic object operations; and implementation of None */
 
 #include "Python.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_object.h"
 #include "pycore_pystate.h"
 #include "pycore_context.h"
@@ -124,7 +124,7 @@ void
 _Py_dump_counts(FILE* f)
 {
     PyInterpreterState *interp = _PyInterpreterState_Get();
-    if (!interp->core_config.show_alloc_count) {
+    if (!interp->config.show_alloc_count) {
         return;
     }
 
@@ -1767,13 +1767,13 @@ PyObject _Py_NotImplementedStruct = {
     1, &_PyNotImplemented_Type
 };
 
-_PyInitError
+PyStatus
 _PyTypes_Init(void)
 {
 #define INIT_TYPE(TYPE, NAME) \
     do { \
         if (PyType_Ready(TYPE) < 0) { \
-            return _Py_INIT_ERR("Can't initialize " NAME " type"); \
+            return _PyStatus_ERR("Can't initialize " NAME " type"); \
         } \
     } while (0)
 
@@ -1843,7 +1843,7 @@ _PyTypes_Init(void)
     INIT_TYPE(&PyCoro_Type, "coroutine");
     INIT_TYPE(&_PyCoroWrapper_Type, "coroutine wrapper");
     INIT_TYPE(&_PyInterpreterID_Type, "interpreter ID");
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 
 #undef INIT_TYPE
 }
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index dc1d0e5ad0d4..72556adb6207 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -46,7 +46,7 @@ static void
 show_track(void)
 {
     PyInterpreterState *interp = _PyInterpreterState_Get();
-    if (!interp->core_config.show_alloc_count) {
+    if (!interp->config.show_alloc_count) {
         return;
     }
 
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 0aa5e4ad18dd..0fe7b5658bef 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -40,7 +40,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_fileutils.h"
 #include "pycore_object.h"
 #include "pycore_pylifecycle.h"
@@ -3549,9 +3549,9 @@ PyUnicode_EncodeFSDefault(PyObject *unicode)
                                    interp->fs_codec.errors);
     }
     else {
-        const _PyCoreConfig *config = &interp->core_config;
+        const wchar_t *filesystem_errors = interp->config.filesystem_errors;
         _Py_error_handler errors;
-        errors = get_error_handler_wide(config->filesystem_errors);
+        errors = get_error_handler_wide(filesystem_errors);
         assert(errors != _Py_ERROR_UNKNOWN);
         return unicode_encode_utf8(unicode, errors, NULL);
     }
@@ -3567,9 +3567,9 @@ PyUnicode_EncodeFSDefault(PyObject *unicode)
                                          interp->fs_codec.errors);
     }
     else {
-        const _PyCoreConfig *config = &interp->core_config;
+        const wchar_t *filesystem_errors = interp->config.filesystem_errors;
         _Py_error_handler errors;
-        errors = get_error_handler_wide(config->filesystem_errors);
+        errors = get_error_handler_wide(filesystem_errors);
         assert(errors != _Py_ERROR_UNKNOWN);
         return unicode_encode_locale(unicode, errors, 0);
     }
@@ -3787,9 +3787,9 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
                                    NULL);
     }
     else {
-        const _PyCoreConfig *config = &interp->core_config;
+        const wchar_t *filesystem_errors = interp->config.filesystem_errors;
         _Py_error_handler errors;
-        errors = get_error_handler_wide(config->filesystem_errors);
+        errors = get_error_handler_wide(filesystem_errors);
         assert(errors != _Py_ERROR_UNKNOWN);
         return unicode_decode_utf8(s, size, errors, NULL, NULL);
     }
@@ -3805,9 +3805,9 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
                                 interp->fs_codec.errors);
     }
     else {
-        const _PyCoreConfig *config = &interp->core_config;
+        const wchar_t *filesystem_errors = interp->config.filesystem_errors;
         _Py_error_handler errors;
-        errors = get_error_handler_wide(config->filesystem_errors);
+        errors = get_error_handler_wide(filesystem_errors);
         return unicode_decode_locale(s, size, errors, 0);
     }
 #endif
@@ -15200,7 +15200,7 @@ PyTypeObject PyUnicode_Type = {
 
 /* Initialize the Unicode implementation */
 
-_PyInitError
+PyStatus
 _PyUnicode_Init(void)
 {
     /* XXX - move this array to unicodectype.c ? */
@@ -15218,12 +15218,12 @@ _PyUnicode_Init(void)
     /* Init the implementation */
     _Py_INCREF_UNICODE_EMPTY();
     if (!unicode_empty) {
-        return _Py_INIT_ERR("Can't create empty string");
+        return _PyStatus_ERR("Can't create empty string");
     }
     Py_DECREF(unicode_empty);
 
     if (PyType_Ready(&PyUnicode_Type) < 0) {
-        return _Py_INIT_ERR("Can't initialize unicode type");
+        return _PyStatus_ERR("Can't initialize unicode type");
     }
 
     /* initialize the linebreak bloom filter */
@@ -15232,15 +15232,15 @@ _PyUnicode_Init(void)
         Py_ARRAY_LENGTH(linebreak));
 
     if (PyType_Ready(&EncodingMapType) < 0) {
-         return _Py_INIT_ERR("Can't initialize encoding map type");
+         return _PyStatus_ERR("Can't initialize encoding map type");
     }
     if (PyType_Ready(&PyFieldNameIter_Type) < 0) {
-        return _Py_INIT_ERR("Can't initialize field name iterator type");
+        return _PyStatus_ERR("Can't initialize field name iterator type");
     }
     if (PyType_Ready(&PyFormatterIter_Type) < 0) {
-        return _Py_INIT_ERR("Can't initialize formatter iter type");
+        return _PyStatus_ERR("Can't initialize formatter iter type");
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 /* Finalize the Unicode implementation */
@@ -15718,23 +15718,23 @@ config_get_codec_name(wchar_t **config_encoding)
 }
 
 
-static _PyInitError
+static PyStatus
 init_stdio_encoding(PyInterpreterState *interp)
 {
     /* Update the stdio encoding to the normalized Python codec name. */
-    _PyCoreConfig *config = &interp->core_config;
+    PyConfig *config = &interp->config;
     if (config_get_codec_name(&config->stdio_encoding) < 0) {
-        return _Py_INIT_ERR("failed to get the Python codec name "
+        return _PyStatus_ERR("failed to get the Python codec name "
                             "of the stdio encoding");
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
 static int
 init_fs_codec(PyInterpreterState *interp)
 {
-    _PyCoreConfig *config = &interp->core_config;
+    PyConfig *config = &interp->config;
 
     _Py_error_handler error_handler;
     error_handler = get_error_handler_wide(config->filesystem_errors);
@@ -15778,31 +15778,31 @@ init_fs_codec(PyInterpreterState *interp)
 }
 
 
-static _PyInitError
+static PyStatus
 init_fs_encoding(PyInterpreterState *interp)
 {
     /* Update the filesystem encoding to the normalized Python codec name.
        For example, replace "ANSI_X3.4-1968" (locale encoding) with "ascii"
        (Python codec name). */
-    _PyCoreConfig *config = &interp->core_config;
+    PyConfig *config = &interp->config;
     if (config_get_codec_name(&config->filesystem_encoding) < 0) {
-        return _Py_INIT_ERR("failed to get the Python codec "
+        return _PyStatus_ERR("failed to get the Python codec "
                             "of the filesystem encoding");
     }
 
     if (init_fs_codec(interp) < 0) {
-        return _Py_INIT_ERR("cannot initialize filesystem codec");
+        return _PyStatus_ERR("cannot initialize filesystem codec");
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-_PyInitError
+PyStatus
 _PyUnicode_InitEncodings(PyInterpreterState *interp)
 {
-    _PyInitError err = init_fs_encoding(interp);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = init_fs_encoding(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     return init_stdio_encoding(interp);
@@ -15814,7 +15814,7 @@ int
 _PyUnicode_EnableLegacyWindowsFSEncoding(void)
 {
     PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
-    _PyCoreConfig *config = &interp->core_config;
+    PyConfig *config = &interp->config;
 
     /* Set the filesystem encoding to mbcs/replace (PEP 529) */
     wchar_t *encoding = _PyMem_RawWcsdup(L"mbcs");
diff --git a/PC/getpathp.c b/PC/getpathp.c
index 62c42ecefe9e..e86cf13a4910 100644
--- a/PC/getpathp.c
+++ b/PC/getpathp.c
@@ -80,7 +80,7 @@
 
 
 #include "Python.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_pystate.h"
 #include "osdefs.h"
 #include <wchar.h>
@@ -272,10 +272,10 @@ typedef HRESULT(__stdcall *PPathCchCanonicalizeEx) (PWSTR pszPathOut, size_t cch
     PCWSTR pszPathIn, unsigned long dwFlags);
 static PPathCchCanonicalizeEx _PathCchCanonicalizeEx;
 
-static _PyInitError canonicalize(wchar_t *buffer, const wchar_t *path)
+static PyStatus canonicalize(wchar_t *buffer, const wchar_t *path)
 {
     if (buffer == NULL) {
-        return _Py_INIT_NO_MEMORY();
+        return _PyStatus_NO_MEMORY();
     }
 
     if (_PathCchCanonicalizeEx_Initialized == 0) {
@@ -291,15 +291,15 @@ static _PyInitError canonicalize(wchar_t *buffer, const wchar_t *path)
 
     if (_PathCchCanonicalizeEx) {
         if (FAILED(_PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, path, 0))) {
-            return _Py_INIT_ERR("buffer overflow in getpathp.c's canonicalize()");
+            return _PyStatus_ERR("buffer overflow in getpathp.c's canonicalize()");
         }
     }
     else {
         if (!PathCanonicalizeW(buffer, path)) {
-            return _Py_INIT_ERR("buffer overflow in getpathp.c's canonicalize()");
+            return _PyStatus_ERR("buffer overflow in getpathp.c's canonicalize()");
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -529,9 +529,9 @@ _Py_GetDLLPath(void)
 }
 
 
-static _PyInitError
-get_program_full_path(const _PyCoreConfig *core_config,
-                      PyCalculatePath *calculate, _PyPathConfig *config)
+static PyStatus
+get_program_full_path(const PyConfig *config,
+                      PyCalculatePath *calculate, _PyPathConfig *pathconfig)
 {
     const wchar_t *pyvenv_launcher;
     wchar_t program_full_path[MAXPATHLEN+1];
@@ -544,19 +544,19 @@ get_program_full_path(const _PyCoreConfig *core_config,
         wcscpy_s(program_full_path, MAXPATHLEN+1, pyvenv_launcher);
     } else if (!GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) {
         /* GetModuleFileName should never fail when passed NULL */
-        return _Py_INIT_ERR("Cannot determine program path");
+        return _PyStatus_ERR("Cannot determine program path");
     }
 
-    config->program_full_path = PyMem_RawMalloc(
+    pathconfig->program_full_path = PyMem_RawMalloc(
         sizeof(wchar_t) * (MAXPATHLEN + 1));
 
-    return canonicalize(config->program_full_path,
+    return canonicalize(pathconfig->program_full_path,
                         program_full_path);
 }
 
 
 static int
-read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path)
+read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path)
 {
     FILE *sp_file = _Py_wfopen(path, L"r");
     if (sp_file == NULL) {
@@ -565,8 +565,8 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path)
 
     wcscpy_s(prefix, MAXPATHLEN+1, path);
     reduce(prefix);
-    config->isolated = 1;
-    config->site_import = 0;
+    pathconfig->isolated = 1;
+    pathconfig->site_import = 0;
 
     size_t bufsiz = MAXPATHLEN;
     size_t prefixlen = wcslen(prefix);
@@ -594,7 +594,7 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path)
         }
 
         if (strcmp(line, "import site") == 0) {
-            config->site_import = 1;
+            pathconfig->site_import = 1;
             continue;
         }
         else if (strncmp(line, "import ", 7) == 0) {
@@ -642,7 +642,7 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path)
     }
 
     fclose(sp_file);
-    config->module_search_path = buf;
+    pathconfig->module_search_path = buf;
     return 1;
 
 error:
@@ -654,25 +654,25 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path)
 
 static void
 calculate_init(PyCalculatePath *calculate,
-               const _PyCoreConfig *core_config)
+               const PyConfig *config)
 {
-    calculate->home = core_config->home;
+    calculate->home = config->home;
     calculate->path_env = _wgetenv(L"PATH");
 }
 
 
 static int
-get_pth_filename(wchar_t *spbuffer, _PyPathConfig *config)
+get_pth_filename(wchar_t *spbuffer, _PyPathConfig *pathconfig)
 {
-    if (config->dll_path[0]) {
-        if (!change_ext(spbuffer, config->dll_path, L"._pth") &&
+    if (pathconfig->dll_path[0]) {
+        if (!change_ext(spbuffer, pathconfig->dll_path, L"._pth") &&
             exists(spbuffer))
         {
             return 1;
         }
     }
-    if (config->program_full_path[0]) {
-        if (!change_ext(spbuffer, config->program_full_path, L"._pth") &&
+    if (pathconfig->program_full_path[0]) {
+        if (!change_ext(spbuffer, pathconfig->program_full_path, L"._pth") &&
             exists(spbuffer))
         {
             return 1;
@@ -683,15 +683,15 @@ get_pth_filename(wchar_t *spbuffer, _PyPathConfig *config)
 
 
 static int
-calculate_pth_file(_PyPathConfig *config, wchar_t *prefix)
+calculate_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix)
 {
     wchar_t spbuffer[MAXPATHLEN+1];
 
-    if (!get_pth_filename(spbuffer, config)) {
+    if (!get_pth_filename(spbuffer, pathconfig)) {
         return 0;
     }
 
-    return read_pth_file(config, prefix, spbuffer);
+    return read_pth_file(pathconfig, prefix, spbuffer);
 }
 
 
@@ -735,7 +735,7 @@ calculate_pyvenv_file(PyCalculatePath *calculate)
 }
 
 
-#define INIT_ERR_BUFFER_OVERFLOW() _Py_INIT_ERR("buffer overflow")
+#define INIT_ERR_BUFFER_OVERFLOW() _PyStatus_ERR("buffer overflow")
 
 
 static void
@@ -760,9 +760,9 @@ calculate_home_prefix(PyCalculatePath *calculate, wchar_t *prefix)
 }
 
 
-static _PyInitError
-calculate_module_search_path(const _PyCoreConfig *core_config,
-                             PyCalculatePath *calculate, _PyPathConfig *config,
+static PyStatus
+calculate_module_search_path(const PyConfig *config,
+                             PyCalculatePath *calculate, _PyPathConfig *pathconfig,
                              wchar_t *prefix)
 {
     int skiphome = calculate->home==NULL ? 0 : 1;
@@ -772,7 +772,7 @@ calculate_module_search_path(const _PyCoreConfig *core_config,
 #endif
     /* We only use the default relative PYTHONPATH if we haven't
        anything better to use! */
-    int skipdefault = (core_config->module_search_path_env != NULL ||
+    int skipdefault = (config->pythonpath_env != NULL ||
                        calculate->home != NULL ||
                        calculate->machine_path != NULL ||
                        calculate->user_path != NULL);
@@ -811,8 +811,8 @@ calculate_module_search_path(const _PyCoreConfig *core_config,
         bufsz += wcslen(calculate->machine_path) + 1;
     }
     bufsz += wcslen(calculate->zip_path) + 1;
-    if (core_config->module_search_path_env != NULL) {
-        bufsz += wcslen(core_config->module_search_path_env) + 1;
+    if (config->pythonpath_env != NULL) {
+        bufsz += wcslen(config->pythonpath_env) + 1;
     }
 
     wchar_t *buf, *start_buf;
@@ -820,21 +820,21 @@ calculate_module_search_path(const _PyCoreConfig *core_config,
     if (buf == NULL) {
         /* We can't exit, so print a warning and limp along */
         fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
-        if (core_config->module_search_path_env) {
+        if (config->pythonpath_env) {
             fprintf(stderr, "Using environment $PYTHONPATH.\n");
-            config->module_search_path = core_config->module_search_path_env;
+            pathconfig->module_search_path = config->pythonpath_env;
         }
         else {
             fprintf(stderr, "Using default static path.\n");
-            config->module_search_path = PYTHONPATH;
+            pathconfig->module_search_path = PYTHONPATH;
         }
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
     start_buf = buf;
 
-    if (core_config->module_search_path_env) {
+    if (config->pythonpath_env) {
         if (wcscpy_s(buf, bufsz - (buf - start_buf),
-                     core_config->module_search_path_env)) {
+                     config->pythonpath_env)) {
             return INIT_ERR_BUFFER_OVERFLOW();
         }
         buf = wcschr(buf, L'\0');
@@ -941,38 +941,38 @@ calculate_module_search_path(const _PyCoreConfig *core_config,
         }
     }
 
-    config->module_search_path = start_buf;
-    return _Py_INIT_OK();
+    pathconfig->module_search_path = start_buf;
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-calculate_path_impl(const _PyCoreConfig *core_config,
-                    PyCalculatePath *calculate, _PyPathConfig *config)
+static PyStatus
+calculate_path_impl(const PyConfig *config,
+                    PyCalculatePath *calculate, _PyPathConfig *pathconfig)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    assert(config->dll_path == NULL);
+    assert(pathconfig->dll_path == NULL);
 
-    config->dll_path = _Py_GetDLLPath();
-    if (config->dll_path == NULL) {
-        return _Py_INIT_NO_MEMORY();
+    pathconfig->dll_path = _Py_GetDLLPath();
+    if (pathconfig->dll_path == NULL) {
+        return _PyStatus_NO_MEMORY();
     }
 
-    err = get_program_full_path(core_config, calculate, config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = get_program_full_path(config, calculate, pathconfig);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     /* program_full_path guaranteed \0 terminated in MAXPATH+1 bytes. */
-    wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, config->program_full_path);
+    wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, pathconfig->program_full_path);
     reduce(calculate->argv0_path);
 
     wchar_t prefix[MAXPATHLEN+1];
     memset(prefix, 0, sizeof(prefix));
 
     /* Search for a sys.path file */
-    if (calculate_pth_file(config, prefix)) {
+    if (calculate_pth_file(pathconfig, prefix)) {
         goto done;
     }
 
@@ -980,27 +980,27 @@ calculate_path_impl(const _PyCoreConfig *core_config,
 
     /* Calculate zip archive path from DLL or exe path */
     change_ext(calculate->zip_path,
-               config->dll_path[0] ? config->dll_path : config->program_full_path,
+               pathconfig->dll_path[0] ? pathconfig->dll_path : pathconfig->program_full_path,
                L".zip");
 
     calculate_home_prefix(calculate, prefix);
 
-    err = calculate_module_search_path(core_config, calculate, config, prefix);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = calculate_module_search_path(config, calculate, pathconfig, prefix);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
 done:
-    config->prefix = _PyMem_RawWcsdup(prefix);
-    if (config->prefix == NULL) {
-        return _Py_INIT_NO_MEMORY();
+    pathconfig->prefix = _PyMem_RawWcsdup(prefix);
+    if (pathconfig->prefix == NULL) {
+        return _PyStatus_NO_MEMORY();
     }
-    config->exec_prefix = _PyMem_RawWcsdup(prefix);
-    if (config->exec_prefix == NULL) {
-        return _Py_INIT_NO_MEMORY();
+    pathconfig->exec_prefix = _PyMem_RawWcsdup(prefix);
+    if (pathconfig->exec_prefix == NULL) {
+        return _PyStatus_NO_MEMORY();
     }
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -1012,24 +1012,24 @@ calculate_free(PyCalculatePath *calculate)
 }
 
 
-_PyInitError
-_PyPathConfig_Calculate_impl(_PyPathConfig *config, const _PyCoreConfig *core_config)
+PyStatus
+_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
 {
     PyCalculatePath calculate;
     memset(&calculate, 0, sizeof(calculate));
 
-    calculate_init(&calculate, core_config);
+    calculate_init(&calculate, config);
 
-    _PyInitError err = calculate_path_impl(core_config, &calculate, config);
-    if (_Py_INIT_FAILED(err)) {
+    PyStatus status = calculate_path_impl(config, &calculate, pathconfig);
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
-    err = _Py_INIT_OK();
+    status = _PyStatus_OK();
 
 done:
     calculate_free(&calculate);
-    return err;
+    return status;
 }
 
 
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index db691cd39c8b..329f9feb2bdf 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -127,9 +127,9 @@
     <ClInclude Include="..\Include\complexobject.h" />
     <ClInclude Include="..\Include\context.h" />
     <ClInclude Include="..\Include\cpython\abstract.h" />
-    <ClInclude Include="..\Include\cpython\coreconfig.h" />
     <ClInclude Include="..\Include\cpython\dictobject.h" />
     <ClInclude Include="..\Include\cpython\fileobject.h" />
+    <ClInclude Include="..\Include\cpython\initconfig.h" />
     <ClInclude Include="..\Include\cpython\object.h" />
     <ClInclude Include="..\Include\cpython\objimpl.h" />
     <ClInclude Include="..\Include\cpython\pyerrors.h" />
@@ -161,11 +161,11 @@
     <ClInclude Include="..\Include\internal\pycore_ceval.h" />
     <ClInclude Include="..\Include\internal\pycore_condvar.h" />
     <ClInclude Include="..\Include\internal\pycore_context.h" />
-    <ClInclude Include="..\Include\internal\pycore_coreconfig.h" />
     <ClInclude Include="..\Include\internal\pycore_fileutils.h" />
     <ClInclude Include="..\Include\internal\pycore_getopt.h" />
     <ClInclude Include="..\Include\internal\pycore_gil.h" />
     <ClInclude Include="..\Include\internal\pycore_hamt.h" />
+    <ClInclude Include="..\Include\internal\pycore_initconfig.h" />
     <ClInclude Include="..\Include\internal\pycore_object.h" />
     <ClInclude Include="..\Include\internal\pycore_pathconfig.h" />
     <ClInclude Include="..\Include\internal\pycore_pyerrors.h" />
@@ -420,7 +420,6 @@
     <ClCompile Include="..\Python\codecs.c" />
     <ClCompile Include="..\Python\compile.c" />
     <ClCompile Include="..\Python\context.c" />
-    <ClCompile Include="..\Python\coreconfig.c" />
     <ClCompile Include="..\Python\dynamic_annotations.c" />
     <ClCompile Include="..\Python\dynload_win.c" />
     <ClCompile Include="..\Python\errors.c" />
@@ -438,6 +437,7 @@
     <ClCompile Include="..\Python\hamt.c" />
     <ClCompile Include="..\Python\import.c" />
     <ClCompile Include="..\Python\importdl.c" />
+    <ClCompile Include="..\Python\initconfig.c" />
     <ClCompile Include="..\Python\marshal.c" />
     <ClCompile Include="..\Python\modsupport.c" />
     <ClCompile Include="..\Python\mysnprintf.c" />
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
index dba47e9aa2d1..d80d05fb15a0 100644
--- a/PCbuild/pythoncore.vcxproj.filters
+++ b/PCbuild/pythoncore.vcxproj.filters
@@ -84,15 +84,15 @@
     <ClInclude Include="..\Include\cpython\abstract.h">
       <Filter>Include</Filter>
     </ClInclude>
-    <ClInclude Include="..\Include\cpython\coreconfig.h">
-      <Filter>Include</Filter>
-    </ClInclude>
     <ClInclude Include="..\Include\cpython\dictobject.h">
       <Filter>Include</Filter>
     </ClInclude>
     <ClInclude Include="..\Include\cpython\fileobject.h">
       <Filter>Include</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\cpython\initconfig.h">
+      <Filter>Include</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\cpython\object.h">
       <Filter>Include</Filter>
     </ClInclude>
@@ -186,9 +186,6 @@
     <ClInclude Include="..\Include\internal\pycore_context.h">
       <Filter>Include</Filter>
     </ClInclude>
-    <ClInclude Include="..\Include\internal\pycore_coreconfig.h">
-      <Filter>Include</Filter>
-    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_fileutils.h">
       <Filter>Include</Filter>
     </ClInclude>
@@ -201,6 +198,9 @@
     <ClInclude Include="..\Include\internal\pycore_hamt.h">
       <Filter>Include</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_initconfig.h">
+      <Filter>Include</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_object.h">
       <Filter>Include</Filter>
     </ClInclude>
@@ -920,9 +920,6 @@
     <ClCompile Include="..\Python\compile.c">
       <Filter>Python</Filter>
     </ClCompile>
-    <ClCompile Include="..\Python\coreconfig.c">
-      <Filter>Python</Filter>
-    </ClCompile>
     <ClCompile Include="..\Python\context.h">
       <Filter>Python</Filter>
     </ClCompile>
@@ -977,6 +974,9 @@
     <ClCompile Include="..\Python\importdl.c">
       <Filter>Python</Filter>
     </ClCompile>
+    <ClCompile Include="..\Python\initconfig.c">
+      <Filter>Python</Filter>
+    </ClCompile>
     <ClCompile Include="..\Python\marshal.c">
       <Filter>Python</Filter>
     </ClCompile>
diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c
index 8cf44d33bc02..13375b0a3819 100644
--- a/Programs/_freeze_importlib.c
+++ b/Programs/_freeze_importlib.c
@@ -36,7 +36,7 @@ main(int argc, char *argv[])
     const char *name, *inpath, *outpath;
     char buf[100];
     FILE *infile = NULL, *outfile = NULL;
-    struct _Py_stat_struct status;
+    struct _Py_stat_struct stat;
     size_t text_size, data_size, i, n;
     char *text = NULL;
     unsigned char *data;
@@ -56,11 +56,11 @@ main(int argc, char *argv[])
         fprintf(stderr, "cannot open '%s' for reading\n", inpath);
         goto error;
     }
-    if (_Py_fstat_noraise(fileno(infile), &status)) {
+    if (_Py_fstat_noraise(fileno(infile), &stat)) {
         fprintf(stderr, "cannot fstat '%s'\n", inpath);
         goto error;
     }
-    text_size = (size_t)status.st_size;
+    text_size = (size_t)stat.st_size;
     text = (char *) malloc(text_size + 1);
     if (text == NULL) {
         fprintf(stderr, "could not allocate %ld bytes\n", (long) text_size);
@@ -76,32 +76,32 @@ main(int argc, char *argv[])
     }
     text[text_size] = '\0';
 
-    _PyInitError err;
-    _PyCoreConfig config;
+    PyStatus status;
+    PyConfig config;
 
-    err = _PyCoreConfig_InitIsolatedConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _PyCoreConfig_Clear(&config);
-        _Py_ExitInitError(err);
+    status = PyConfig_InitIsolatedConfig(&config);
+    if (PyStatus_Exception(status)) {
+        PyConfig_Clear(&config);
+        Py_ExitStatusException(status);
     }
 
     config.site_import = 0;
 
-    err = _PyCoreConfig_SetString(&config, &config.program_name,
+    status = PyConfig_SetString(&config, &config.program_name,
                                   L"./_freeze_importlib");
-    if (_PyInitError_Failed(err)) {
-        _PyCoreConfig_Clear(&config);
-        _Py_ExitInitError(err);
+    if (PyStatus_Exception(status)) {
+        PyConfig_Clear(&config);
+        Py_ExitStatusException(status);
     }
 
     /* Don't install importlib, since it could execute outdated bytecode. */
     config._install_importlib = 0;
     config._init_main = 0;
 
-    err = _Py_InitializeFromConfig(&config);
-    _PyCoreConfig_Clear(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    PyConfig_Clear(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
     sprintf(buf, "<frozen %s>", name);
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index de1c5877f0f5..3e1210e04d82 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -4,7 +4,7 @@
 #endif
 
 #include <Python.h>
-#include "pycore_coreconfig.h"   /* FIXME: PEP 587 makes these functions public */
+#include "pycore_initconfig.h"   /* FIXME: PEP 587 makes these functions public */
 #include <Python.h>
 #include "pythread.h"
 #include <inttypes.h>
@@ -328,25 +328,25 @@ static int test_init_initialize_config(void)
 
 static int check_init_compat_config(int preinit)
 {
-    _PyInitError err;
+    PyStatus status;
 
     if (preinit) {
-        _PyPreConfig preconfig;
+        PyPreConfig preconfig;
         _PyPreConfig_InitCompatConfig(&preconfig);
 
-        err = _Py_PreInitialize(&preconfig);
-        if (_PyInitError_Failed(err)) {
-            _Py_ExitInitError(err);
+        status = Py_PreInitialize(&preconfig);
+        if (PyStatus_Exception(status)) {
+            Py_ExitStatusException(status);
         }
     }
 
-    _PyCoreConfig config;
-    _PyCoreConfig_InitCompatConfig(&config);
+    PyConfig config;
+    _PyConfig_InitCompatConfig(&config);
     config.program_name = L"./_testembed";
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
     dump_config();
@@ -418,9 +418,9 @@ static int test_init_global_config(void)
 
 static int test_init_from_config(void)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    _PyPreConfig preconfig;
+    PyPreConfig preconfig;
     _PyPreConfig_InitCompatConfig(&preconfig);
 
     putenv("PYTHONMALLOC=malloc_debug");
@@ -430,14 +430,14 @@ static int test_init_from_config(void)
     Py_UTF8Mode = 0;
     preconfig.utf8_mode = 1;
 
-    err = _Py_PreInitialize(&preconfig);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_PreInitialize(&preconfig);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
-    /* Test _Py_InitializeFromConfig() */
-    _PyCoreConfig config;
-    _PyCoreConfig_InitCompatConfig(&config);
+    /* Test Py_InitializeFromConfig() */
+    PyConfig config;
+    _PyConfig_InitCompatConfig(&config);
     config.install_signal_handlers = 0;
 
     /* FIXME: test use_environment */
@@ -481,9 +481,9 @@ static int test_init_from_config(void)
     config.parse_argv = 1;
 
     static wchar_t* xoptions[3] = {
-        L"core_xoption1=3",
-        L"core_xoption2=",
-        L"core_xoption3",
+        L"xoption1=3",
+        L"xoption2=",
+        L"xoption3",
     };
     config.xoptions.length = Py_ARRAY_LENGTH(xoptions);
     config.xoptions.items = xoptions;
@@ -494,7 +494,7 @@ static int test_init_from_config(void)
     config.warnoptions.length = Py_ARRAY_LENGTH(warnoptions);
     config.warnoptions.items = warnoptions;
 
-    /* FIXME: test module_search_path_env */
+    /* FIXME: test pythonpath_env */
     /* FIXME: test home */
     /* FIXME: test path config: module_search_path .. dll_path */
 
@@ -553,9 +553,9 @@ static int test_init_from_config(void)
     Py_FrozenFlag = 0;
     config.pathconfig_warnings = 0;
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     dump_config();
     Py_Finalize();
@@ -565,12 +565,12 @@ static int test_init_from_config(void)
 
 static int check_init_parse_argv(int parse_argv)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    PyConfig config;
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
     static wchar_t* argv[] = {
@@ -587,9 +587,9 @@ static int check_init_parse_argv(int parse_argv)
     config.argv.items = argv;
     config.parse_argv = parse_argv;
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     dump_config();
     Py_Finalize();
@@ -652,20 +652,20 @@ static int test_init_compat_env(void)
 
 static int test_init_python_env(void)
 {
-    _PyInitError err;
+    PyStatus status;
 
     set_all_env_vars();
 
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    PyConfig config;
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     config.program_name = L"./_testembed";
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     dump_config();
     Py_Finalize();
@@ -708,13 +708,13 @@ static int test_init_env_dev_mode_alloc(void)
 
 static int test_init_isolated_flag(void)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    /* Test _PyCoreConfig.isolated=1 */
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    /* Test PyConfig.isolated=1 */
+    PyConfig config;
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
     Py_IsolatedFlag = 0;
@@ -724,9 +724,9 @@ static int test_init_isolated_flag(void)
     config.program_name = L"./_testembed";
 
     set_all_env_vars();
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     dump_config();
     Py_Finalize();
@@ -734,28 +734,28 @@ static int test_init_isolated_flag(void)
 }
 
 
-/* _PyPreConfig.isolated=1, _PyCoreConfig.isolated=0 */
+/* PyPreConfig.isolated=1, PyConfig.isolated=0 */
 static int test_preinit_isolated1(void)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    _PyPreConfig preconfig;
+    PyPreConfig preconfig;
     _PyPreConfig_InitCompatConfig(&preconfig);
     preconfig.isolated = 1;
 
-    err = _Py_PreInitialize(&preconfig);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_PreInitialize(&preconfig);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
-    _PyCoreConfig config;
-    _PyCoreConfig_InitCompatConfig(&config);
+    PyConfig config;
+    _PyConfig_InitCompatConfig(&config);
     config.program_name = L"./_testembed";
 
     set_all_env_vars();
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     dump_config();
     Py_Finalize();
@@ -763,23 +763,23 @@ static int test_preinit_isolated1(void)
 }
 
 
-/* _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1 */
+/* PyPreConfig.isolated=0, PyConfig.isolated=1 */
 static int test_preinit_isolated2(void)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    _PyPreConfig preconfig;
+    PyPreConfig preconfig;
     _PyPreConfig_InitCompatConfig(&preconfig);
     preconfig.isolated = 0;
 
-    err = _Py_PreInitialize(&preconfig);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_PreInitialize(&preconfig);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
-    /* Test _PyCoreConfig.isolated=1 */
-    _PyCoreConfig config;
-    _PyCoreConfig_InitCompatConfig(&config);
+    /* Test PyConfig.isolated=1 */
+    PyConfig config;
+    _PyConfig_InitCompatConfig(&config);
 
     Py_IsolatedFlag = 0;
     config.isolated = 1;
@@ -788,9 +788,9 @@ static int test_preinit_isolated2(void)
     config.program_name = L"./_testembed";
 
     set_all_env_vars();
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     dump_config();
     Py_Finalize();
@@ -800,10 +800,10 @@ static int test_preinit_isolated2(void)
 
 static int test_preinit_dont_parse_argv(void)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    _PyPreConfig preconfig;
-    _PyPreConfig_InitIsolatedConfig(&preconfig);
+    PyPreConfig preconfig;
+    PyPreConfig_InitIsolatedConfig(&preconfig);
 
     preconfig.isolated = 0;
 
@@ -814,15 +814,15 @@ static int test_preinit_dont_parse_argv(void)
                        L"-X", L"dev",
                        L"-X", L"utf8",
                        L"script.py"};
-    err = _Py_PreInitializeFromWideArgs(&preconfig, Py_ARRAY_LENGTH(argv), argv);
-    if (_PyInitError_Failed(err)) {
+    status = Py_PreInitializeFromArgs(&preconfig, Py_ARRAY_LENGTH(argv), argv);
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
 
-    _PyCoreConfig config;
+    PyConfig config;
 
-    err = _PyCoreConfig_InitIsolatedConfig(&config);
-    if (_PyInitError_Failed(err)) {
+    status = PyConfig_InitIsolatedConfig(&config);
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
 
@@ -830,70 +830,70 @@ static int test_preinit_dont_parse_argv(void)
 
     /* Pre-initialize implicitly using argv: make sure that -X dev
        is used to configure the allocation in preinitialization */
-    err = _PyCoreConfig_SetWideArgv(&config, Py_ARRAY_LENGTH(argv), argv);
-    if (_PyInitError_Failed(err)) {
+    status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
 
-    err = _PyCoreConfig_SetString(&config, &config.program_name,
+    status = PyConfig_SetString(&config, &config.program_name,
                                   L"./_testembed");
-    if (_PyInitError_Failed(err)) {
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
-    _PyCoreConfig_Clear(&config);
+    PyConfig_Clear(&config);
 
     dump_config();
     Py_Finalize();
     return 0;
 
 failed:
-    _PyCoreConfig_Clear(&config);
-    _Py_ExitInitError(err);
+    PyConfig_Clear(&config);
+    Py_ExitStatusException(status);
 }
 
 
 static int test_preinit_parse_argv(void)
 {
-    _PyInitError err;
-    _PyCoreConfig config;
+    PyStatus status;
+    PyConfig config;
 
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
 
     /* Pre-initialize implicitly using argv: make sure that -X dev
        is used to configure the allocation in preinitialization */
     wchar_t *argv[] = {L"python3", L"-X", L"dev", L"script.py"};
-    err = _PyCoreConfig_SetWideArgv(&config, Py_ARRAY_LENGTH(argv), argv);
-    if (_PyInitError_Failed(err)) {
+    status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
 
-    err = _PyCoreConfig_SetString(&config, &config.program_name,
+    status = PyConfig_SetString(&config, &config.program_name,
                                   L"./_testembed");
-    if (_PyInitError_Failed(err)) {
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
-    _PyCoreConfig_Clear(&config);
+    PyConfig_Clear(&config);
 
     dump_config();
     Py_Finalize();
     return 0;
 
 failed:
-    _PyCoreConfig_Clear(&config);
-    _Py_ExitInitError(err);
+    PyConfig_Clear(&config);
+    Py_ExitStatusException(status);
 }
 
 
@@ -923,8 +923,8 @@ static void set_all_global_config_variables(void)
 
 static int check_preinit_isolated_config(int preinit)
 {
-    _PyInitError err;
-    _PyPreConfig *rt_preconfig;
+    PyStatus status;
+    PyPreConfig *rt_preconfig;
 
     /* environment variables must be ignored */
     set_all_env_vars();
@@ -933,12 +933,12 @@ static int check_preinit_isolated_config(int preinit)
     set_all_global_config_variables();
 
     if (preinit) {
-        _PyPreConfig preconfig;
-        _PyPreConfig_InitIsolatedConfig(&preconfig);
+        PyPreConfig preconfig;
+        PyPreConfig_InitIsolatedConfig(&preconfig);
 
-        err = _Py_PreInitialize(&preconfig);
-        if (_PyInitError_Failed(err)) {
-            _Py_ExitInitError(err);
+        status = Py_PreInitialize(&preconfig);
+        if (PyStatus_Exception(status)) {
+            Py_ExitStatusException(status);
         }
 
         rt_preconfig = &_PyRuntime.preconfig;
@@ -946,18 +946,18 @@ static int check_preinit_isolated_config(int preinit)
         assert(rt_preconfig->use_environment == 0);
     }
 
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitIsolatedConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _PyCoreConfig_Clear(&config);
-        _Py_ExitInitError(err);
+    PyConfig config;
+    status = PyConfig_InitIsolatedConfig(&config);
+    if (PyStatus_Exception(status)) {
+        PyConfig_Clear(&config);
+        Py_ExitStatusException(status);
     }
     config.program_name = L"./_testembed";
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _PyCoreConfig_Clear(&config);
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        PyConfig_Clear(&config);
+        Py_ExitStatusException(status);
     }
 
     rt_preconfig = &_PyRuntime.preconfig;
@@ -984,7 +984,7 @@ static int test_init_isolated_config(void)
 
 static int check_init_python_config(int preinit)
 {
-    _PyInitError err;
+    PyStatus status;
 
     /* global configuration variables must be ignored */
     set_all_global_config_variables();
@@ -1000,25 +1000,25 @@ static int check_init_python_config(int preinit)
 #endif
 
     if (preinit) {
-        _PyPreConfig preconfig;
-        _PyPreConfig_InitPythonConfig(&preconfig);
+        PyPreConfig preconfig;
+        PyPreConfig_InitPythonConfig(&preconfig);
 
-        err = _Py_PreInitialize(&preconfig);
-        if (_PyInitError_Failed(err)) {
-            _Py_ExitInitError(err);
+        status = Py_PreInitialize(&preconfig);
+        if (PyStatus_Exception(status)) {
+            Py_ExitStatusException(status);
         }
     }
 
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    PyConfig config;
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     config.program_name = L"./_testembed";
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     dump_config();
     Py_Finalize();
@@ -1040,28 +1040,28 @@ static int test_init_python_config(void)
 
 static int test_init_dont_configure_locale(void)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    _PyPreConfig preconfig;
-    _PyPreConfig_InitPythonConfig(&preconfig);
+    PyPreConfig preconfig;
+    PyPreConfig_InitPythonConfig(&preconfig);
     preconfig.configure_locale = 0;
     preconfig.coerce_c_locale = 1;
     preconfig.coerce_c_locale_warn = 1;
 
-    err = _Py_PreInitialize(&preconfig);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_PreInitialize(&preconfig);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    PyConfig config;
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     config.program_name = L"./_testembed";
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
     dump_config();
@@ -1072,19 +1072,19 @@ static int test_init_dont_configure_locale(void)
 
 static int test_init_dev_mode(void)
 {
-    _PyInitError err;
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    PyStatus status;
+    PyConfig config;
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     putenv("PYTHONFAULTHANDLER=");
     putenv("PYTHONMALLOC=");
     config.dev_mode = 1;
     config.program_name = L"./_testembed";
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     dump_config();
     Py_Finalize();
@@ -1250,39 +1250,39 @@ static int test_audit_subinterpreter(void)
 
 static int test_init_read_set(void)
 {
-    _PyInitError err;
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    PyStatus status;
+    PyConfig config;
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
-    err = _PyCoreConfig_DecodeLocale(&config, &config.program_name,
+    status = PyConfig_SetBytesString(&config, &config.program_name,
                                      "./init_read_set");
-    if (_PyInitError_Failed(err)) {
+    if (PyStatus_Exception(status)) {
         goto fail;
     }
 
-    err = _PyCoreConfig_Read(&config);
-    if (_PyInitError_Failed(err)) {
+    status = PyConfig_Read(&config);
+    if (PyStatus_Exception(status)) {
         goto fail;
     }
 
-    if (_PyWstrList_Append(&config.module_search_paths,
-                           L"init_read_set_path") < 0) {
-        err = _PyInitError_NoMemory();
+    status = PyWideStringList_Append(&config.module_search_paths,
+                                     L"init_read_set_path");
+    if (PyStatus_Exception(status)) {
         goto fail;
     }
 
-    /* override executable computed by _PyCoreConfig_Read() */
-    err = _PyCoreConfig_SetString(&config, &config.executable, L"my_executable");
-    if (_PyInitError_Failed(err)) {
+    /* override executable computed by PyConfig_Read() */
+    status = PyConfig_SetString(&config, &config.executable, L"my_executable");
+    if (PyStatus_Exception(status)) {
         goto fail;
     }
 
-    err = _Py_InitializeFromConfig(&config);
-    _PyCoreConfig_Clear(&config);
-    if (_PyInitError_Failed(err)) {
+    status = Py_InitializeFromConfig(&config);
+    PyConfig_Clear(&config);
+    if (PyStatus_Exception(status)) {
         goto fail;
     }
     dump_config();
@@ -1290,7 +1290,7 @@ static int test_init_read_set(void)
     return 0;
 
 fail:
-    _Py_ExitInitError(err);
+    Py_ExitStatusException(status);
 }
 
 
@@ -1301,7 +1301,7 @@ wchar_t *init_main_argv[] = {
     L"arg2"};
 
 
-static void configure_init_main(_PyCoreConfig *config)
+static void configure_init_main(PyConfig *config)
 {
     config->argv.length = Py_ARRAY_LENGTH(init_main_argv);
     config->argv.items = init_main_argv;
@@ -1312,38 +1312,38 @@ static void configure_init_main(_PyCoreConfig *config)
 
 static int test_init_run_main(void)
 {
-    _PyInitError err;
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    PyStatus status;
+    PyConfig config;
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     configure_init_main(&config);
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
-    return _Py_RunMain();
+    return Py_RunMain();
 }
 
 
 static int test_init_main(void)
 {
-    _PyInitError err;
-    _PyCoreConfig config;
+    PyStatus status;
+    PyConfig config;
 
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
     configure_init_main(&config);
     config._init_main = 0;
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
     /* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */
@@ -1355,51 +1355,51 @@ static int test_init_main(void)
         exit(1);
     }
 
-    err = _Py_InitializeMain();
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = _Py_InitializeMain();
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
-    return _Py_RunMain();
+    return Py_RunMain();
 }
 
 
 static int test_run_main(void)
 {
-    _PyInitError err;
-    _PyCoreConfig config;
+    PyStatus status;
+    PyConfig config;
 
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
 
     wchar_t *argv[] = {L"python3", L"-c",
                        (L"import sys; "
-                        L"print(f'_Py_RunMain(): sys.argv={sys.argv}')"),
+                        L"print(f'Py_RunMain(): sys.argv={sys.argv}')"),
                        L"arg2"};
-    err = _PyCoreConfig_SetWideArgv(&config, Py_ARRAY_LENGTH(argv), argv);
-    if (_PyInitError_Failed(err)) {
+    status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
 
-    err = _PyCoreConfig_SetString(&config, &config.program_name,
+    status = PyConfig_SetString(&config, &config.program_name,
                                   L"./python3");
-    if (_PyInitError_Failed(err)) {
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_PyInitError_Failed(err)) {
+    status = Py_InitializeFromConfig(&config);
+    if (PyStatus_Exception(status)) {
         goto failed;
     }
-    _PyCoreConfig_Clear(&config);
+    PyConfig_Clear(&config);
 
-    return _Py_RunMain();
+    return Py_RunMain();
 
 failed:
-    _PyCoreConfig_Clear(&config);
-    _Py_ExitInitError(err);
+    PyConfig_Clear(&config);
+    Py_ExitStatusException(status);
 }
 
 
diff --git a/Programs/python.c b/Programs/python.c
index 4c12d38c53b9..1cc3c42cfcbf 100644
--- a/Programs/python.c
+++ b/Programs/python.c
@@ -13,6 +13,6 @@ wmain(int argc, wchar_t **argv)
 int
 main(int argc, char **argv)
 {
-    return _Py_UnixMain(argc, argv);
+    return Py_BytesMain(argc, argv);
 }
 #endif
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index ff5a51216939..5d5808530e11 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -2824,7 +2824,7 @@ _PyBuiltin_Init(void)
 {
     PyObject *mod, *dict, *debug;
 
-    const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
+    const PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config;
 
     if (PyType_Ready(&PyFilter_Type) < 0 ||
         PyType_Ready(&PyMap_Type) < 0 ||
diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c
index fe71cc388a07..43f5264d8625 100644
--- a/Python/bootstrap_hash.c
+++ b/Python/bootstrap_hash.c
@@ -1,5 +1,5 @@
 #include "Python.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #ifdef MS_WINDOWS
 #  include <windows.h>
 /* All sample MSDN wincrypt programs include the header below. It is at least
@@ -547,14 +547,14 @@ _PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
 }
 
 
-_PyInitError
-_Py_HashRandomization_Init(const _PyCoreConfig *config)
+PyStatus
+_Py_HashRandomization_Init(const PyConfig *config)
 {
     void *secret = &_Py_HashSecret;
     Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
 
     if (_Py_HashSecret_Initialized) {
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
     _Py_HashSecret_Initialized = 1;
 
@@ -579,11 +579,11 @@ _Py_HashRandomization_Init(const _PyCoreConfig *config)
            pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
         res = pyurandom(secret, secret_size, 0, 0);
         if (res < 0) {
-            return _Py_INIT_ERR("failed to get random numbers "
+            return _PyStatus_ERR("failed to get random numbers "
                                 "to initialize Python");
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
diff --git a/Python/compile.c b/Python/compile.c
index 734e8401ff02..425d0d68ac4a 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -311,7 +311,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags,
     PyCodeObject *co = NULL;
     PyCompilerFlags local_flags;
     int merged;
-    _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
+    PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config;
 
     if (!__doc__) {
         __doc__ = PyUnicode_InternFromString("__doc__");
@@ -4782,7 +4782,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
                 return compiler_error(c, "'await' outside function");
             }
 
-            if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && 
+            if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
                     c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){
                 return compiler_error(c, "'await' outside async function");
             }
diff --git a/Python/dynload_hpux.c b/Python/dynload_hpux.c
index f275e534588a..da9baa4b9989 100644
--- a/Python/dynload_hpux.c
+++ b/Python/dynload_hpux.c
@@ -20,7 +20,7 @@ dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix,
                                        const char *pathname, FILE *fp)
 {
     int flags = BIND_FIRST | BIND_DEFERRED;
-    int verbose = _PyInterpreterState_GET_UNSAFE()->core_config.verbose;
+    int verbose = _PyInterpreterState_GET_UNSAFE()->config.verbose;
     if (verbose) {
         flags = BIND_FIRST | BIND_IMMEDIATE |
             BIND_NONFATAL | BIND_VERBOSE;
diff --git a/Python/errors.c b/Python/errors.c
index 831f111eead2..bd33d4d340f6 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -2,7 +2,7 @@
 /* Error handling */
 
 #include "Python.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_pyerrors.h"
 #include "pycore_pystate.h"
 #include "pycore_traceback.h"
@@ -1090,16 +1090,16 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = {
 };
 
 
-_PyInitError
+PyStatus
 _PyErr_Init(void)
 {
     if (UnraisableHookArgsType.tp_name == NULL) {
         if (PyStructSequence_InitType2(&UnraisableHookArgsType,
                                        &UnraisableHookArgs_desc) < 0) {
-            return _Py_INIT_ERR("failed to initialize UnraisableHookArgs type");
+            return _PyStatus_ERR("failed to initialize UnraisableHookArgs type");
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
diff --git a/Python/frozenmain.c b/Python/frozenmain.c
index c3af080401e9..c56938ab4899 100644
--- a/Python/frozenmain.c
+++ b/Python/frozenmain.c
@@ -16,9 +16,9 @@ extern int PyInitFrozenExtensions(void);
 int
 Py_FrozenMain(int argc, char **argv)
 {
-    _PyInitError err = _PyRuntime_Initialize();
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    PyStatus status = _PyRuntime_Initialize();
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
     const char *p;
@@ -39,11 +39,11 @@ Py_FrozenMain(int argc, char **argv)
         }
     }
 
-    _PyCoreConfig config;
-    err = _PyCoreConfig_InitPythonConfig(&config);
-    if (_PyInitError_Failed(err)) {
-        _PyCoreConfig_Clear(&config);
-        _Py_ExitInitError(err);
+    PyConfig config;
+    status = PyConfig_InitPythonConfig(&config);
+    if (PyStatus_Exception(status)) {
+        PyConfig_Clear(&config);
+        Py_ExitStatusException(status);
     }
     config.pathconfig_warnings = 0;   /* Suppress errors from getpath.c */
 
@@ -85,10 +85,10 @@ Py_FrozenMain(int argc, char **argv)
     if (argc >= 1)
         Py_SetProgramName(argv_copy[0]);
 
-    err = _Py_InitializeFromConfig(&config);
-    _PyCoreConfig_Clear(&config);
-    if (_PyInitError_Failed(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    PyConfig_Clear(&config);
+    if (PyStatus_Exception(status)) {
+        Py_ExitStatusException(status);
     }
 
 #ifdef MS_WINDOWS
diff --git a/Python/import.c b/Python/import.c
index ec172b29f739..41a5c01cadf3 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -43,17 +43,17 @@ module _imp
 
 /* Initialize things */
 
-_PyInitError
+PyStatus
 _PyImport_Init(PyInterpreterState *interp)
 {
     interp->builtins_copy = PyDict_Copy(interp->builtins);
     if (interp->builtins_copy == NULL) {
-        return _Py_INIT_ERR("Can't backup builtins dict");
+        return _PyStatus_ERR("Can't backup builtins dict");
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
-_PyInitError
+PyStatus
 _PyImportHooks_Init(void)
 {
     PyObject *v, *path_hooks = NULL;
@@ -82,15 +82,15 @@ _PyImportHooks_Init(void)
         goto error;
     }
     Py_DECREF(path_hooks);
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 
   error:
     PyErr_Print();
-    return _Py_INIT_ERR("initializing sys.meta_path, sys.path_hooks, "
+    return _PyStatus_ERR("initializing sys.meta_path, sys.path_hooks, "
                         "or path_importer_cache failed");
 }
 
-_PyInitError
+PyStatus
 _PyImportZip_Init(PyInterpreterState *interp)
 {
     PyObject *path_hooks, *zipimport;
@@ -102,7 +102,7 @@ _PyImportZip_Init(PyInterpreterState *interp)
         goto error;
     }
 
-    int verbose = interp->core_config.verbose;
+    int verbose = interp->config.verbose;
     if (verbose) {
         PySys_WriteStderr("# installing zipimport hook\n");
     }
@@ -138,11 +138,11 @@ _PyImportZip_Init(PyInterpreterState *interp)
         }
     }
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 
   error:
     PyErr_Print();
-    return _Py_INIT_ERR("initializing zipimport failed");
+    return _PyStatus_ERR("initializing zipimport failed");
 }
 
 /* Locking primitives to prevent parallel imports of the same module
@@ -418,7 +418,7 @@ PyImport_Cleanup(void)
 
     /* XXX Perhaps these precautions are obsolete. Who knows? */
 
-    int verbose = interp->core_config.verbose;
+    int verbose = interp->config.verbose;
     if (verbose) {
         PySys_WriteStderr("# clear builtins._\n");
     }
@@ -766,7 +766,7 @@ _PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename,
         PyMapping_DelItem(modules, name);
         return NULL;
     }
-    int verbose = _PyInterpreterState_Get()->core_config.verbose;
+    int verbose = _PyInterpreterState_Get()->config.verbose;
     if (verbose) {
         PySys_FormatStderr("import %U # previously loaded (%R)\n",
                            name, filename);
@@ -1455,7 +1455,7 @@ remove_importlib_frames(PyInterpreterState *interp)
        which end with a call to "_call_with_frames_removed". */
 
     PyErr_Fetch(&exception, &value, &base_tb);
-    if (!exception || interp->core_config.verbose) {
+    if (!exception || interp->config.verbose) {
         goto done;
     }
 
@@ -1655,7 +1655,7 @@ import_find_and_load(PyObject *abs_name)
     _Py_IDENTIFIER(_find_and_load);
     PyObject *mod = NULL;
     PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
-    int import_time = interp->core_config.import_time;
+    int import_time = interp->config.import_time;
     static int import_level;
     static _PyTime_t accumulated;
 
@@ -2338,7 +2338,7 @@ PyInit__imp(void)
         goto failure;
     }
 
-    const wchar_t *mode = _PyInterpreterState_Get()->core_config.check_hash_pycs_mode;
+    const wchar_t *mode = _PyInterpreterState_Get()->config.check_hash_pycs_mode;
     PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1);
     if (pyc_mode == NULL) {
         goto failure;
diff --git a/Python/coreconfig.c b/Python/initconfig.c
similarity index 71%
rename from Python/coreconfig.c
rename to Python/initconfig.c
index 89ccff4c9b76..66b1b305a560 100644
--- a/Python/coreconfig.c
+++ b/Python/initconfig.c
@@ -1,6 +1,6 @@
 #include "Python.h"
 #include "osdefs.h"       /* DELIM */
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_fileutils.h"
 #include "pycore_getopt.h"
 #include "pycore_pylifecycle.h"
@@ -202,39 +202,39 @@ _Py_GetGlobalVariablesAsDict(void)
 }
 
 
-/* --- _PyInitError ----------------------------------------------- */
+/* --- PyStatus ----------------------------------------------- */
 
-_PyInitError _PyInitError_Ok(void)
-{ return _Py_INIT_OK(); }
+PyStatus PyStatus_Ok(void)
+{ return _PyStatus_OK(); }
 
-_PyInitError _PyInitError_Error(const char *err_msg)
+PyStatus PyStatus_Error(const char *err_msg)
 {
-    return (_PyInitError){._type = _Py_INIT_ERR_TYPE_ERROR,
+    return (PyStatus){._type = _PyStatus_TYPE_ERROR,
                           .err_msg = err_msg};
 }
 
-_PyInitError _PyInitError_NoMemory(void)
-{ return _PyInitError_Error("memory allocation failed"); }
+PyStatus PyStatus_NoMemory(void)
+{ return PyStatus_Error("memory allocation failed"); }
 
-_PyInitError _PyInitError_Exit(int exitcode)
-{ return _Py_INIT_EXIT(exitcode); }
+PyStatus PyStatus_Exit(int exitcode)
+{ return _PyStatus_EXIT(exitcode); }
 
 
-int _PyInitError_IsError(_PyInitError err)
-{ return _Py_INIT_IS_ERROR(err); }
+int PyStatus_IsError(PyStatus status)
+{ return _PyStatus_IS_ERROR(status); }
 
-int _PyInitError_IsExit(_PyInitError err)
-{ return _Py_INIT_IS_EXIT(err); }
+int PyStatus_IsExit(PyStatus status)
+{ return _PyStatus_IS_EXIT(status); }
 
-int _PyInitError_Failed(_PyInitError err)
-{ return _Py_INIT_FAILED(err); }
+int PyStatus_Exception(PyStatus status)
+{ return _PyStatus_EXCEPTION(status); }
 
 
-/* --- _PyWstrList ------------------------------------------------ */
+/* --- PyWideStringList ------------------------------------------------ */
 
 #ifndef NDEBUG
 int
-_PyWstrList_CheckConsistency(const _PyWstrList *list)
+_PyWideStringList_CheckConsistency(const PyWideStringList *list)
 {
     assert(list->length >= 0);
     if (list->length != 0) {
@@ -249,9 +249,9 @@ _PyWstrList_CheckConsistency(const _PyWstrList *list)
 
 
 void
-_PyWstrList_Clear(_PyWstrList *list)
+_PyWideStringList_Clear(PyWideStringList *list)
 {
-    assert(_PyWstrList_CheckConsistency(list));
+    assert(_PyWideStringList_CheckConsistency(list));
     for (Py_ssize_t i=0; i < list->length; i++) {
         PyMem_RawFree(list->items[i]);
     }
@@ -262,17 +262,17 @@ _PyWstrList_Clear(_PyWstrList *list)
 
 
 int
-_PyWstrList_Copy(_PyWstrList *list, const _PyWstrList *list2)
+_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
 {
-    assert(_PyWstrList_CheckConsistency(list));
-    assert(_PyWstrList_CheckConsistency(list2));
+    assert(_PyWideStringList_CheckConsistency(list));
+    assert(_PyWideStringList_CheckConsistency(list2));
 
     if (list2->length == 0) {
-        _PyWstrList_Clear(list);
+        _PyWideStringList_Clear(list);
         return 0;
     }
 
-    _PyWstrList copy = _PyWstrList_INIT;
+    PyWideStringList copy = PyWideStringList_INIT;
 
     size_t size = list2->length * sizeof(list2->items[0]);
     copy.items = PyMem_RawMalloc(size);
@@ -283,60 +283,61 @@ _PyWstrList_Copy(_PyWstrList *list, const _PyWstrList *list2)
     for (Py_ssize_t i=0; i < list2->length; i++) {
         wchar_t *item = _PyMem_RawWcsdup(list2->items[i]);
         if (item == NULL) {
-            _PyWstrList_Clear(&copy);
+            _PyWideStringList_Clear(&copy);
             return -1;
         }
         copy.items[i] = item;
         copy.length = i + 1;
     }
 
-    _PyWstrList_Clear(list);
+    _PyWideStringList_Clear(list);
     *list = copy;
     return 0;
 }
 
 
-int
-_PyWstrList_Append(_PyWstrList *list, const wchar_t *item)
+PyStatus
+PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
 {
     if (list->length == PY_SSIZE_T_MAX) {
         /* lenght+1 would overflow */
-        return -1;
+        return _PyStatus_NO_MEMORY();
     }
 
     wchar_t *item2 = _PyMem_RawWcsdup(item);
     if (item2 == NULL) {
-        return -1;
+        return _PyStatus_NO_MEMORY();
     }
 
     size_t size = (list->length + 1) * sizeof(list->items[0]);
     wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size);
     if (items2 == NULL) {
         PyMem_RawFree(item2);
-        return -1;
+        return _PyStatus_NO_MEMORY();
     }
 
     items2[list->length] = item2;
     list->items = items2;
     list->length++;
-    return 0;
+    return _PyStatus_OK();
 }
 
 
-int
-_PyWstrList_Extend(_PyWstrList *list, const _PyWstrList *list2)
+PyStatus
+_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
 {
     for (Py_ssize_t i = 0; i < list2->length; i++) {
-        if (_PyWstrList_Append(list, list2->items[i])) {
-            return -1;
+        PyStatus status = PyWideStringList_Append(list, list2->items[i]);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
-    return 0;
+    return _PyStatus_OK();
 }
 
 
 static int
-_PyWstrList_Find(_PyWstrList *list, const wchar_t *item)
+_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
 {
     for (Py_ssize_t i = 0; i < list->length; i++) {
         if (wcscmp(list->items[i], item) == 0) {
@@ -348,9 +349,9 @@ _PyWstrList_Find(_PyWstrList *list, const wchar_t *item)
 
 
 PyObject*
-_PyWstrList_AsList(const _PyWstrList *list)
+_PyWideStringList_AsList(const PyWideStringList *list)
 {
-    assert(_PyWstrList_CheckConsistency(list));
+    assert(_PyWideStringList_CheckConsistency(list));
 
     PyObject *pylist = PyList_New(list->length);
     if (pylist == NULL) {
@@ -457,7 +458,7 @@ _Py_ClearStandardStreamEncoding(void)
 /* --- Py_GetArgcArgv() ------------------------------------------- */
 
 /* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
-static _PyWstrList orig_argv = {.length = 0, .items = NULL};
+static PyWideStringList orig_argv = {.length = 0, .items = NULL};
 
 
 void
@@ -466,7 +467,7 @@ _Py_ClearArgcArgv(void)
     PyMemAllocatorEx old_alloc;
     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 
-    _PyWstrList_Clear(&orig_argv);
+    _PyWideStringList_Clear(&orig_argv);
 
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 }
@@ -475,13 +476,13 @@ _Py_ClearArgcArgv(void)
 static int
 _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
 {
-    const _PyWstrList argv_list = {.length = argc, .items = (wchar_t **)argv};
+    const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv};
     int res;
 
     PyMemAllocatorEx old_alloc;
     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 
-    res = _PyWstrList_Copy(&orig_argv, &argv_list);
+    res = _PyWideStringList_Copy(&orig_argv, &argv_list);
 
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
     return res;
@@ -498,16 +499,16 @@ Py_GetArgcArgv(int *argc, wchar_t ***argv)
 }
 
 
-/* --- _PyCoreConfig ---------------------------------------------- */
+/* --- PyConfig ---------------------------------------------- */
 
 #define DECODE_LOCALE_ERR(NAME, LEN) \
     (((LEN) == -2) \
-     ? _Py_INIT_ERR("cannot decode " NAME) \
-     : _Py_INIT_NO_MEMORY())
+     ? _PyStatus_ERR("cannot decode " NAME) \
+     : _PyStatus_NO_MEMORY())
 
 /* Free memory allocated in config, but don't clear all attributes */
 void
-_PyCoreConfig_Clear(_PyCoreConfig *config)
+PyConfig_Clear(PyConfig *config)
 {
 #define CLEAR(ATTR) \
     do { \
@@ -516,15 +517,15 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
     } while (0)
 
     CLEAR(config->pycache_prefix);
-    CLEAR(config->module_search_path_env);
+    CLEAR(config->pythonpath_env);
     CLEAR(config->home);
     CLEAR(config->program_name);
 
-    _PyWstrList_Clear(&config->argv);
-    _PyWstrList_Clear(&config->warnoptions);
-    _PyWstrList_Clear(&config->xoptions);
-    _PyWstrList_Clear(&config->module_search_paths);
-    config->use_module_search_paths = 0;
+    _PyWideStringList_Clear(&config->argv);
+    _PyWideStringList_Clear(&config->warnoptions);
+    _PyWideStringList_Clear(&config->xoptions);
+    _PyWideStringList_Clear(&config->module_search_paths);
+    config->module_search_paths_set = 0;
 
     CLEAR(config->executable);
     CLEAR(config->prefix);
@@ -545,7 +546,7 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
 
 
 void
-_PyCoreConfig_InitCompatConfig(_PyCoreConfig *config)
+_PyConfig_InitCompatConfig(PyConfig *config)
 {
     memset(config, 0, sizeof(*config));
 
@@ -558,7 +559,7 @@ _PyCoreConfig_InitCompatConfig(_PyCoreConfig *config)
     config->use_hash_seed = -1;
     config->faulthandler = -1;
     config->tracemalloc = -1;
-    config->use_module_search_paths = 0;
+    config->module_search_paths_set = 0;
     config->parse_argv = 0;
     config->site_import = -1;
     config->bytes_warning = -1;
@@ -583,9 +584,9 @@ _PyCoreConfig_InitCompatConfig(_PyCoreConfig *config)
 
 
 static void
-_PyCoreConfig_InitDefaults(_PyCoreConfig *config)
+config_init_defaults(PyConfig *config)
 {
-    _PyCoreConfig_InitCompatConfig(config);
+    _PyConfig_InitCompatConfig(config);
 
     config->isolated = 0;
     config->use_environment = 1;
@@ -607,23 +608,23 @@ _PyCoreConfig_InitDefaults(_PyCoreConfig *config)
 }
 
 
-_PyInitError
-_PyCoreConfig_InitPythonConfig(_PyCoreConfig *config)
+PyStatus
+PyConfig_InitPythonConfig(PyConfig *config)
 {
-    _PyCoreConfig_InitDefaults(config);
+    config_init_defaults(config);
 
     config->_config_init = (int)_PyConfig_INIT_PYTHON;
     config->configure_c_stdio = 1;
     config->parse_argv = 1;
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-_PyInitError
-_PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config)
+PyStatus
+PyConfig_InitIsolatedConfig(PyConfig *config)
 {
-    _PyCoreConfig_InitDefaults(config);
+    config_init_defaults(config);
 
     config->_config_init = (int)_PyConfig_INIT_ISOLATED;
     config->isolated = 1;
@@ -639,25 +640,24 @@ _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config)
     config->legacy_windows_stdio = 0;
 #endif
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
 /* Copy str into *config_str (duplicate the string) */
-_PyInitError
-_PyCoreConfig_SetString(_PyCoreConfig *config, wchar_t **config_str,
-                        const wchar_t *str)
+PyStatus
+PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
 {
-    _PyInitError err = _Py_PreInitializeFromCoreConfig(config, NULL);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     wchar_t *str2;
     if (str != NULL) {
         str2 = _PyMem_RawWcsdup(str);
         if (str2 == NULL) {
-            return _Py_INIT_NO_MEMORY();
+            return _PyStatus_NO_MEMORY();
         }
     }
     else {
@@ -665,17 +665,17 @@ _PyCoreConfig_SetString(_PyCoreConfig *config, wchar_t **config_str,
     }
     PyMem_RawFree(*config_str);
     *config_str = str2;
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-_PyCoreConfig_DecodeLocaleErr(_PyCoreConfig *config, wchar_t **config_str,
-                              const char *str, const char *decode_err_msg)
+static PyStatus
+config_set_bytes_string(PyConfig *config, wchar_t **config_str,
+                        const char *str, const char *decode_err_msg)
 {
-    _PyInitError err = _Py_PreInitializeFromCoreConfig(config, NULL);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     wchar_t *str2;
@@ -684,10 +684,10 @@ _PyCoreConfig_DecodeLocaleErr(_PyCoreConfig *config, wchar_t **config_str,
         str2 = Py_DecodeLocale(str, &len);
         if (str2 == NULL) {
             if (len == (size_t)-2) {
-                return _Py_INIT_ERR(decode_err_msg);
+                return _PyStatus_ERR(decode_err_msg);
             }
             else {
-                return  _Py_INIT_NO_MEMORY();
+                return  _PyStatus_NO_MEMORY();
             }
         }
     }
@@ -696,43 +696,43 @@ _PyCoreConfig_DecodeLocaleErr(_PyCoreConfig *config, wchar_t **config_str,
     }
     PyMem_RawFree(*config_str);
     *config_str = str2;
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-#define CONFIG_DECODE_LOCALE(config, config_str, str, NAME) \
-    _PyCoreConfig_DecodeLocaleErr(config, config_str, str, "cannot decode " NAME)
+#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \
+    config_set_bytes_string(config, config_str, str, "cannot decode " NAME)
 
 
 /* Decode str using Py_DecodeLocale() and set the result into *config_str.
    Pre-initialize Python if needed to ensure that encodings are properly
    configured. */
-_PyInitError
-_PyCoreConfig_DecodeLocale(_PyCoreConfig *config, wchar_t **config_str,
+PyStatus
+PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
                            const char *str)
 {
-    return CONFIG_DECODE_LOCALE(config, config_str, str, "string");
+    return CONFIG_SET_BYTES_STR(config, config_str, str, "string");
 }
 
 
-_PyInitError
-_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
+PyStatus
+_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
 {
-    _PyInitError err;
-    _PyCoreConfig_Clear(config);
+    PyStatus status;
+    PyConfig_Clear(config);
 
 #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
 #define COPY_WSTR_ATTR(ATTR) \
     do { \
-        err = _PyCoreConfig_SetString(config, &config->ATTR, config2->ATTR); \
-        if (_Py_INIT_FAILED(err)) { \
-            return err; \
+        status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \
+        if (_PyStatus_EXCEPTION(status)) { \
+            return status; \
         } \
     } while (0)
 #define COPY_WSTRLIST(LIST) \
     do { \
-        if (_PyWstrList_Copy(&config->LIST, &config2->LIST) < 0 ) { \
-            return _Py_INIT_NO_MEMORY(); \
+        if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0 ) { \
+            return _PyStatus_NO_MEMORY(); \
         } \
     } while (0)
 
@@ -753,7 +753,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
     COPY_ATTR(malloc_stats);
 
     COPY_WSTR_ATTR(pycache_prefix);
-    COPY_WSTR_ATTR(module_search_path_env);
+    COPY_WSTR_ATTR(pythonpath_env);
     COPY_WSTR_ATTR(home);
     COPY_WSTR_ATTR(program_name);
 
@@ -762,7 +762,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
     COPY_WSTRLIST(warnoptions);
     COPY_WSTRLIST(xoptions);
     COPY_WSTRLIST(module_search_paths);
-    COPY_ATTR(use_module_search_paths);
+    COPY_ATTR(module_search_paths_set);
 
     COPY_WSTR_ATTR(executable);
     COPY_WSTR_ATTR(prefix);
@@ -800,12 +800,12 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
 #undef COPY_ATTR
 #undef COPY_WSTR_ATTR
 #undef COPY_WSTRLIST
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
 static PyObject *
-_PyCoreConfig_AsDict(const _PyCoreConfig *config)
+config_as_dict(const PyConfig *config)
 {
     PyObject *dict;
 
@@ -837,7 +837,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
 #define SET_ITEM_WSTR(ATTR) \
     SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR))
 #define SET_ITEM_WSTRLIST(LIST) \
-    SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST))
+    SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST))
 
     SET_ITEM_INT(_config_init);
     SET_ITEM_INT(isolated);
@@ -861,7 +861,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
     SET_ITEM_WSTRLIST(argv);
     SET_ITEM_WSTRLIST(xoptions);
     SET_ITEM_WSTRLIST(warnoptions);
-    SET_ITEM_WSTR(module_search_path_env);
+    SET_ITEM_WSTR(pythonpath_env);
     SET_ITEM_WSTR(home);
     SET_ITEM_WSTRLIST(module_search_paths);
     SET_ITEM_WSTR(executable);
@@ -911,7 +911,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
 
 
 static const char*
-_PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
+config_get_env(const PyConfig *config, const char *name)
 {
     return _Py_GetEnv(config->use_environment, name);
 }
@@ -920,46 +920,46 @@ _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
 /* Get a copy of the environment variable as wchar_t*.
    Return 0 on success, but *dest can be NULL.
    Return -1 on memory allocation failure. Return -2 on decoding error. */
-static _PyInitError
-_PyCoreConfig_GetEnvDup(_PyCoreConfig *config,
-                        wchar_t **dest,
-                        wchar_t *wname, char *name,
-                        const char *decode_err_msg)
+static PyStatus
+config_get_env_dup(PyConfig *config,
+                   wchar_t **dest,
+                   wchar_t *wname, char *name,
+                   const char *decode_err_msg)
 {
     assert(*dest == NULL);
     assert(config->use_environment >= 0);
 
     if (!config->use_environment) {
         *dest = NULL;
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
 #ifdef MS_WINDOWS
     const wchar_t *var = _wgetenv(wname);
     if (!var || var[0] == '\0') {
         *dest = NULL;
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
-    return _PyCoreConfig_SetString(config, dest, var);
+    return PyConfig_SetString(config, dest, var);
 #else
     const char *var = getenv(name);
     if (!var || var[0] == '\0') {
         *dest = NULL;
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
-    return _PyCoreConfig_DecodeLocaleErr(config, dest, var, decode_err_msg);
+    return config_set_bytes_string(config, dest, var, decode_err_msg);
 #endif
 }
 
 
 #define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \
-    _PyCoreConfig_GetEnvDup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
+    config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME)
 
 
 static void
-_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
+config_get_global_vars(PyConfig *config)
 {
     if (config->_config_init != _PyConfig_INIT_COMPAT) {
         /* Python and Isolated configuration ignore global variables */
@@ -1001,7 +1001,7 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
 
 /* Set Py_xxx global configuration variables from 'config' configuration. */
 static void
-_PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
+config_set_global_vars(const PyConfig *config)
 {
 #define COPY_FLAG(ATTR, VAR) \
         if (config->ATTR != -1) { \
@@ -1042,19 +1042,19 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
 
 /* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__
    environment variables on macOS if available. */
-static _PyInitError
-config_init_program_name(_PyCoreConfig *config)
+static PyStatus
+config_init_program_name(PyConfig *config)
 {
-    _PyInitError err;
+    PyStatus status;
 
     /* If Py_SetProgramName() was called, use its value */
     const wchar_t *program_name = _Py_path_config.program_name;
     if (program_name != NULL) {
         config->program_name = _PyMem_RawWcsdup(program_name);
         if (config->program_name == NULL) {
-            return _Py_INIT_NO_MEMORY();
+            return _PyStatus_NO_MEMORY();
         }
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
 #ifdef __APPLE__
@@ -1067,14 +1067,14 @@ config_init_program_name(_PyCoreConfig *config)
        so the actual executable path is passed in an environment variable.
        See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
        script. */
-    const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE");
+    const char *p = config_get_env(config, "PYTHONEXECUTABLE");
     if (p != NULL) {
-        err = CONFIG_DECODE_LOCALE(config, &config->program_name, p,
-                                   "PYTHONEXECUTABLE environment variable");
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = CONFIG_SET_BYTES_STR(config, &config->program_name, p,
+                                      "PYTHONEXECUTABLE environment variable");
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 #ifdef WITH_NEXT_FRAMEWORK
     else {
@@ -1083,26 +1083,27 @@ config_init_program_name(_PyCoreConfig *config)
             /* Used by Mac/Tools/pythonw.c to forward
              * the argv0 of the stub executable
              */
-            err = CONFIG_DECODE_LOCALE(config,
-                                       &config->program_name, pyvenv_launcher,
-                                       "__PYVENV_LAUNCHER__ environment variable");
-            if (_Py_INIT_FAILED(err)) {
-                return err;
+            status = CONFIG_SET_BYTES_STR(config,
+                                          &config->program_name,
+                                          pyvenv_launcher,
+                                          "__PYVENV_LAUNCHER__ environment variable");
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
-            return _Py_INIT_OK();
+            return _PyStatus_OK();
         }
     }
 #endif   /* WITH_NEXT_FRAMEWORK */
 #endif   /* __APPLE__ */
 
     /* Use argv[0] if available and non-empty */
-    const _PyWstrList *argv = &config->argv;
+    const PyWideStringList *argv = &config->argv;
     if (argv->length >= 1 && argv->items[0][0] != L'\0') {
         config->program_name = _PyMem_RawWcsdup(argv->items[0]);
         if (config->program_name == NULL) {
-            return _Py_INIT_NO_MEMORY();
+            return _PyStatus_NO_MEMORY();
         }
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     /* Last fall back: hardcoded name */
@@ -1111,54 +1112,54 @@ config_init_program_name(_PyCoreConfig *config)
 #else
     const wchar_t *default_program_name = L"python3";
 #endif
-    err = _PyCoreConfig_SetString(config, &config->program_name,
-                                  default_program_name);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = PyConfig_SetString(config, &config->program_name,
+                                default_program_name);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
-static _PyInitError
-config_init_executable(_PyCoreConfig *config)
+static PyStatus
+config_init_executable(PyConfig *config)
 {
     assert(config->executable == NULL);
 
     /* If Py_SetProgramFullPath() was called, use its value */
     const wchar_t *program_full_path = _Py_path_config.program_full_path;
     if (program_full_path != NULL) {
-        _PyInitError err = _PyCoreConfig_SetString(config,
-                                                   &config->executable,
-                                                   program_full_path);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        PyStatus status = PyConfig_SetString(config,
+                                             &config->executable,
+                                             program_full_path);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
 static const wchar_t*
-config_get_xoption(const _PyCoreConfig *config, wchar_t *name)
+config_get_xoption(const PyConfig *config, wchar_t *name)
 {
     return _Py_get_xoption(&config->xoptions, name);
 }
 
 
-static _PyInitError
-config_init_home(_PyCoreConfig *config)
+static PyStatus
+config_init_home(PyConfig *config)
 {
     assert(config->home == NULL);
 
     /* If Py_SetPythonHome() was called, use its value */
     wchar_t *home = _Py_path_config.home;
     if (home) {
-        _PyInitError err = _PyCoreConfig_SetString(config, &config->home, home);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        PyStatus status = PyConfig_SetString(config, &config->home, home);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     return CONFIG_GET_ENV_DUP(config, &config->home,
@@ -1166,10 +1167,10 @@ config_init_home(_PyCoreConfig *config)
 }
 
 
-static _PyInitError
-config_init_hash_seed(_PyCoreConfig *config)
+static PyStatus
+config_init_hash_seed(PyConfig *config)
 {
-    const char *seed_text = _PyCoreConfig_GetEnv(config, "PYTHONHASHSEED");
+    const char *seed_text = config_get_env(config, "PYTHONHASHSEED");
 
     Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
     /* Convert a text seed to a numeric one */
@@ -1182,7 +1183,7 @@ config_init_hash_seed(_PyCoreConfig *config)
             || seed > 4294967295UL
             || (errno == ERANGE && seed == ULONG_MAX))
         {
-            return _Py_INIT_ERR("PYTHONHASHSEED must be \"random\" "
+            return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" "
                                 "or an integer in range [0; 4294967295]");
         }
         /* Use a specific hash */
@@ -1194,7 +1195,7 @@ config_init_hash_seed(_PyCoreConfig *config)
         config->use_hash_seed = 0;
         config->hash_seed = 0;
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -1216,10 +1217,10 @@ config_wstr_to_int(const wchar_t *wstr, int *result)
 }
 
 
-static _PyInitError
-config_read_env_vars(_PyCoreConfig *config)
+static PyStatus
+config_read_env_vars(PyConfig *config)
 {
-    _PyInitError err;
+    PyStatus status;
     int use_env = config->use_environment;
 
     /* Get environment variables */
@@ -1251,39 +1252,39 @@ config_read_env_vars(_PyCoreConfig *config)
                  "PYTHONLEGACYWINDOWSSTDIO");
 #endif
 
-    if (_PyCoreConfig_GetEnv(config, "PYTHONDUMPREFS")) {
+    if (config_get_env(config, "PYTHONDUMPREFS")) {
         config->dump_refs = 1;
     }
-    if (_PyCoreConfig_GetEnv(config, "PYTHONMALLOCSTATS")) {
+    if (config_get_env(config, "PYTHONMALLOCSTATS")) {
         config->malloc_stats = 1;
     }
 
-    if (config->module_search_path_env == NULL) {
-        err = CONFIG_GET_ENV_DUP(config, &config->module_search_path_env,
-                                 L"PYTHONPATH", "PYTHONPATH");
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+    if (config->pythonpath_env == NULL) {
+        status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
+                                    L"PYTHONPATH", "PYTHONPATH");
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     if (config->use_hash_seed < 0) {
-        err = config_init_hash_seed(config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = config_init_hash_seed(config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-config_init_tracemalloc(_PyCoreConfig *config)
+static PyStatus
+config_init_tracemalloc(PyConfig *config)
 {
     int nframe;
     int valid;
 
-    const char *env = _PyCoreConfig_GetEnv(config, "PYTHONTRACEMALLOC");
+    const char *env = config_get_env(config, "PYTHONTRACEMALLOC");
     if (env) {
         if (!_Py_str_to_int(env, &nframe)) {
             valid = (nframe >= 0);
@@ -1292,7 +1293,7 @@ config_init_tracemalloc(_PyCoreConfig *config)
             valid = 0;
         }
         if (!valid) {
-            return _Py_INIT_ERR("PYTHONTRACEMALLOC: invalid number of frames");
+            return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames");
         }
         config->tracemalloc = nframe;
     }
@@ -1308,8 +1309,8 @@ config_init_tracemalloc(_PyCoreConfig *config)
                 valid = 0;
             }
             if (!valid) {
-                return _Py_INIT_ERR("-X tracemalloc=NFRAME: "
-                                    "invalid number of frames");
+                return _PyStatus_ERR("-X tracemalloc=NFRAME: "
+                                     "invalid number of frames");
             }
         }
         else {
@@ -1318,12 +1319,12 @@ config_init_tracemalloc(_PyCoreConfig *config)
         }
         config->tracemalloc = nframe;
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-config_init_pycache_prefix(_PyCoreConfig *config)
+static PyStatus
+config_init_pycache_prefix(PyConfig *config)
 {
     assert(config->pycache_prefix == NULL);
 
@@ -1333,7 +1334,7 @@ config_init_pycache_prefix(_PyCoreConfig *config)
         if (sep && wcslen(sep) > 1) {
             config->pycache_prefix = _PyMem_RawWcsdup(sep + 1);
             if (config->pycache_prefix == NULL) {
-                return _Py_INIT_NO_MEMORY();
+                return _PyStatus_NO_MEMORY();
             }
         }
         else {
@@ -1341,7 +1342,7 @@ config_init_pycache_prefix(_PyCoreConfig *config)
             // if "-X pycache_prefix=" option is used
             config->pycache_prefix = NULL;
         }
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix,
@@ -1350,41 +1351,41 @@ config_init_pycache_prefix(_PyCoreConfig *config)
 }
 
 
-static _PyInitError
-config_read_complex_options(_PyCoreConfig *config)
+static PyStatus
+config_read_complex_options(PyConfig *config)
 {
     /* More complex options configured by env var and -X option */
     if (config->faulthandler < 0) {
-        if (_PyCoreConfig_GetEnv(config, "PYTHONFAULTHANDLER")
+        if (config_get_env(config, "PYTHONFAULTHANDLER")
            || config_get_xoption(config, L"faulthandler")) {
             config->faulthandler = 1;
         }
     }
-    if (_PyCoreConfig_GetEnv(config, "PYTHONPROFILEIMPORTTIME")
+    if (config_get_env(config, "PYTHONPROFILEIMPORTTIME")
        || config_get_xoption(config, L"importtime")) {
         config->import_time = 1;
     }
 
-    _PyInitError err;
+    PyStatus status;
     if (config->tracemalloc < 0) {
-        err = config_init_tracemalloc(config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = config_init_tracemalloc(config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     if (config->pycache_prefix == NULL) {
-        err = config_init_pycache_prefix(config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = config_init_pycache_prefix(config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
 static const wchar_t *
-config_get_stdio_errors(const _PyCoreConfig *config)
+config_get_stdio_errors(const PyConfig *config)
 {
 #ifndef MS_WINDOWS
     const char *loc = setlocale(LC_CTYPE, NULL);
@@ -1410,65 +1411,65 @@ config_get_stdio_errors(const _PyCoreConfig *config)
 }
 
 
-static _PyInitError
-config_get_locale_encoding(_PyCoreConfig *config, wchar_t **locale_encoding)
+static PyStatus
+config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding)
 {
 #ifdef MS_WINDOWS
     char encoding[20];
     PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
-    return _PyCoreConfig_DecodeLocale(config, locale_encoding, encoding);
+    return PyConfig_SetBytesString(config, locale_encoding, encoding);
 #elif defined(_Py_FORCE_UTF8_LOCALE)
-    return _PyCoreConfig_SetString(config, locale_encoding, L"utf-8");
+    return PyConfig_SetString(config, locale_encoding, L"utf-8");
 #else
     const char *encoding = nl_langinfo(CODESET);
     if (!encoding || encoding[0] == '\0') {
-        return _Py_INIT_ERR("failed to get the locale encoding: "
-                            "nl_langinfo(CODESET) failed");
+        return _PyStatus_ERR("failed to get the locale encoding: "
+                             "nl_langinfo(CODESET) failed");
     }
     /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */
-    return CONFIG_DECODE_LOCALE(config,
+    return CONFIG_SET_BYTES_STR(config,
                                 locale_encoding, encoding,
                                 "nl_langinfo(CODESET)");
 #endif
 }
 
 
-static _PyInitError
-config_init_stdio_encoding(_PyCoreConfig *config,
-                           const _PyPreConfig *preconfig)
+static PyStatus
+config_init_stdio_encoding(PyConfig *config,
+                           const PyPreConfig *preconfig)
 {
-    _PyInitError err;
+    PyStatus status;
 
     /* If Py_SetStandardStreamEncoding() have been called, use these
         parameters. */
     if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) {
-        err = CONFIG_DECODE_LOCALE(config, &config->stdio_encoding,
-                                   _Py_StandardStreamEncoding,
-                                   "_Py_StandardStreamEncoding");
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
+                                      _Py_StandardStreamEncoding,
+                                      "_Py_StandardStreamEncoding");
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) {
-        err = CONFIG_DECODE_LOCALE(config, &config->stdio_errors,
-                                   _Py_StandardStreamErrors,
-                                   "_Py_StandardStreamErrors");
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
+                                      _Py_StandardStreamErrors,
+                                      "_Py_StandardStreamErrors");
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     if (config->stdio_encoding != NULL && config->stdio_errors != NULL) {
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     /* PYTHONIOENCODING environment variable */
-    const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING");
+    const char *opt = config_get_env(config, "PYTHONIOENCODING");
     if (opt) {
         char *pythonioencoding = _PyMem_RawStrdup(opt);
         if (pythonioencoding == NULL) {
-            return _Py_INIT_NO_MEMORY();
+            return _PyStatus_NO_MEMORY();
         }
 
         char *errors = strchr(pythonioencoding, ':');
@@ -1483,12 +1484,12 @@ config_init_stdio_encoding(_PyCoreConfig *config,
         /* Does PYTHONIOENCODING contain an encoding? */
         if (pythonioencoding[0]) {
             if (config->stdio_encoding == NULL) {
-                err = CONFIG_DECODE_LOCALE(config, &config->stdio_encoding,
-                                           pythonioencoding,
-                                           "PYTHONIOENCODING environment variable");
-                if (_Py_INIT_FAILED(err)) {
+                status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding,
+                                              pythonioencoding,
+                                              "PYTHONIOENCODING environment variable");
+                if (_PyStatus_EXCEPTION(status)) {
                     PyMem_RawFree(pythonioencoding);
-                    return err;
+                    return status;
                 }
             }
 
@@ -1502,12 +1503,12 @@ config_init_stdio_encoding(_PyCoreConfig *config,
         }
 
         if (config->stdio_errors == NULL && errors != NULL) {
-            err = CONFIG_DECODE_LOCALE(config, &config->stdio_errors,
-                                       errors,
-                                       "PYTHONIOENCODING environment variable");
-            if (_Py_INIT_FAILED(err)) {
+            status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors,
+                                          errors,
+                                          "PYTHONIOENCODING environment variable");
+            if (_PyStatus_EXCEPTION(status)) {
                 PyMem_RawFree(pythonioencoding);
-                return err;
+                return status;
             }
         }
 
@@ -1517,83 +1518,84 @@ config_init_stdio_encoding(_PyCoreConfig *config,
     /* UTF-8 Mode uses UTF-8/surrogateescape */
     if (preconfig->utf8_mode) {
         if (config->stdio_encoding == NULL) {
-            err = _PyCoreConfig_SetString(config, &config->stdio_encoding, L"utf-8");
-            if (_Py_INIT_FAILED(err)) {
-                return err;
+            status = PyConfig_SetString(config, &config->stdio_encoding,
+                                        L"utf-8");
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
         }
         if (config->stdio_errors == NULL) {
-            err = _PyCoreConfig_SetString(config, &config->stdio_errors,
-                                          L"surrogateescape");
-            if (_Py_INIT_FAILED(err)) {
-                return err;
+            status = PyConfig_SetString(config, &config->stdio_errors,
+                                        L"surrogateescape");
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
         }
     }
 
     /* Choose the default error handler based on the current locale. */
     if (config->stdio_encoding == NULL) {
-        err = config_get_locale_encoding(config, &config->stdio_encoding);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = config_get_locale_encoding(config, &config->stdio_encoding);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
     if (config->stdio_errors == NULL) {
         const wchar_t *errors = config_get_stdio_errors(config);
         assert(errors != NULL);
 
-        err = _PyCoreConfig_SetString(config, &config->stdio_errors, errors);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = PyConfig_SetString(config, &config->stdio_errors, errors);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig)
+static PyStatus
+config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
 {
-    _PyInitError err;
+    PyStatus status;
 
     if (config->filesystem_encoding == NULL) {
 #ifdef _Py_FORCE_UTF8_FS_ENCODING
-        err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
+        status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8");
 #else
 
 #ifdef MS_WINDOWS
         if (preconfig->legacy_windows_fs_encoding) {
             /* Legacy Windows filesystem encoding: mbcs/replace */
-            err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
-                                          L"mbcs");
+            status = PyConfig_SetString(config, &config->filesystem_encoding,
+                                        L"mbcs");
         }
         else
 #endif
         if (preconfig->utf8_mode) {
-            err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
-                                          L"utf-8");
+            status = PyConfig_SetString(config, &config->filesystem_encoding,
+                                        L"utf-8");
         }
 #ifndef MS_WINDOWS
         else if (_Py_GetForceASCII()) {
-            err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
-                                          L"ascii");
+            status = PyConfig_SetString(config, &config->filesystem_encoding,
+                                        L"ascii");
         }
 #endif
         else {
 #ifdef MS_WINDOWS
             /* Windows defaults to utf-8/surrogatepass (PEP 529). */
-            err = _PyCoreConfig_SetString(config, &config->filesystem_encoding,
-                                          L"utf-8");
+            status = PyConfig_SetString(config, &config->filesystem_encoding,
+                                        L"utf-8");
 #else
-            err = config_get_locale_encoding(config,
-                                             &config->filesystem_encoding);
+            status = config_get_locale_encoding(config,
+                                                &config->filesystem_encoding);
 #endif
         }
 #endif   /* !_Py_FORCE_UTF8_FS_ENCODING */
 
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
@@ -1609,25 +1611,25 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig)
 #else
         errors = L"surrogateescape";
 #endif
-        err = _PyCoreConfig_SetString(config, &config->filesystem_errors, errors);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = PyConfig_SetString(config, &config->filesystem_errors, errors);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-config_read(_PyCoreConfig *config)
+static PyStatus
+config_read(PyConfig *config)
 {
-    _PyInitError err;
-    const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
+    PyStatus status;
+    const PyPreConfig *preconfig = &_PyRuntime.preconfig;
 
     if (config->use_environment) {
-        err = config_read_env_vars(config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = config_read_env_vars(config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
@@ -1639,29 +1641,29 @@ config_read(_PyCoreConfig *config)
         config->show_alloc_count = 1;
     }
 
-    err = config_read_complex_options(config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = config_read_complex_options(config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if (config->home == NULL) {
-        err = config_init_home(config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = config_init_home(config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     if (config->executable == NULL) {
-        err = config_init_executable(config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = config_init_executable(config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     if (config->_install_importlib) {
-        err = _PyCoreConfig_InitPathConfig(config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = _PyConfig_InitPathConfig(config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
@@ -1683,29 +1685,30 @@ config_read(_PyCoreConfig *config)
     }
 
     if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
-        err = config_init_fs_encoding(config, preconfig);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = config_init_fs_encoding(config, preconfig);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
-    err = config_init_stdio_encoding(config, preconfig);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = config_init_stdio_encoding(config, preconfig);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if (config->argv.length < 1) {
         /* Ensure at least one (empty) argument is seen */
-        if (_PyWstrList_Append(&config->argv, L"") < 0) {
-            return _Py_INIT_NO_MEMORY();
+        status = PyWideStringList_Append(&config->argv, L"");
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     if (config->check_hash_pycs_mode == NULL) {
-        err = _PyCoreConfig_SetString(config, &config->check_hash_pycs_mode,
-                                      L"default");
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
+                                    L"default");
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
@@ -1713,12 +1716,12 @@ config_read(_PyCoreConfig *config)
         config->configure_c_stdio = 1;
     }
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
 static void
-config_init_stdio(const _PyCoreConfig *config)
+config_init_stdio(const PyConfig *config)
 {
 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
     /* don't translate newlines (\r\n <=> \n) */
@@ -1759,23 +1762,23 @@ config_init_stdio(const _PyCoreConfig *config)
    - set Py_xxx global configuration variables
    - initialize C standard streams (stdin, stdout, stderr) */
 void
-_PyCoreConfig_Write(const _PyCoreConfig *config, _PyRuntimeState *runtime)
+_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
 {
-    _PyCoreConfig_SetGlobalConfig(config);
+    config_set_global_vars(config);
 
     if (config->configure_c_stdio) {
         config_init_stdio(config);
     }
 
     /* Write the new pre-configuration into _PyRuntime */
-    _PyPreConfig *preconfig = &runtime->preconfig;
+    PyPreConfig *preconfig = &runtime->preconfig;
     preconfig->isolated = config->isolated;
     preconfig->use_environment = config->use_environment;
     preconfig->dev_mode = config->dev_mode;
 }
 
 
-/* --- _PyCoreConfig command line parser -------------------------- */
+/* --- PyConfig command line parser -------------------------- */
 
 static void
 config_usage(int error, const wchar_t* program)
@@ -1797,12 +1800,12 @@ config_usage(int error, const wchar_t* program)
 
 
 /* Parse the command line arguments */
-static _PyInitError
-config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
+static PyStatus
+config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
                      Py_ssize_t *opt_index)
 {
-    _PyInitError err;
-    const _PyWstrList *argv = &config->argv;
+    PyStatus status;
+    const PyWideStringList *argv = &config->argv;
     int print_version = 0;
     const wchar_t* program = config->program_name;
 
@@ -1822,7 +1825,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
                 size_t len = wcslen(_PyOS_optarg) + 1 + 1;
                 wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len);
                 if (command == NULL) {
-                    return _Py_INIT_NO_MEMORY();
+                    return _PyStatus_NO_MEMORY();
                 }
                 memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t));
                 command[len - 2] = '\n';
@@ -1839,7 +1842,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
             if (config->run_module == NULL) {
                 config->run_module = _PyMem_RawWcsdup(_PyOS_optarg);
                 if (config->run_module == NULL) {
-                    return _Py_INIT_NO_MEMORY();
+                    return _PyStatus_NO_MEMORY();
                 }
             }
             break;
@@ -1853,16 +1856,16 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
                 || wcscmp(_PyOS_optarg, L"never") == 0
                 || wcscmp(_PyOS_optarg, L"default") == 0)
             {
-                err = _PyCoreConfig_SetString(config, &config->check_hash_pycs_mode,
-                                              _PyOS_optarg);
-                if (_Py_INIT_FAILED(err)) {
-                    return err;
+                status = PyConfig_SetString(config, &config->check_hash_pycs_mode,
+                                            _PyOS_optarg);
+                if (_PyStatus_EXCEPTION(status)) {
+                    return status;
                 }
             } else {
                 fprintf(stderr, "--check-hash-based-pycs must be one of "
                         "'default', 'always', or 'never'\n");
                 config_usage(1, program);
-                return _Py_INIT_EXIT(2);
+                return _PyStatus_EXIT(2);
             }
             break;
 
@@ -1922,15 +1925,16 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
         case 'h':
         case '?':
             config_usage(0, program);
-            return _Py_INIT_EXIT(0);
+            return _PyStatus_EXIT(0);
 
         case 'V':
             print_version++;
             break;
 
         case 'W':
-            if (_PyWstrList_Append(warnoptions, _PyOS_optarg) < 0) {
-                return _Py_INIT_NO_MEMORY();
+            status = PyWideStringList_Append(warnoptions, _PyOS_optarg);
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
             break;
 
@@ -1947,14 +1951,14 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
         default:
             /* unknown argument: parsing failed */
             config_usage(1, program);
-            return _Py_INIT_EXIT(2);
+            return _PyStatus_EXIT(2);
         }
     } while (1);
 
     if (print_version) {
         printf("Python %s\n",
                 (print_version >= 2) ? Py_GetVersion() : PY_VERSION);
-        return _Py_INIT_EXIT(0);
+        return _PyStatus_EXIT(0);
     }
 
     if (config->run_command == NULL && config->run_module == NULL
@@ -1964,7 +1968,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
     {
         config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]);
         if (config->run_filename == NULL) {
-            return _Py_INIT_NO_MEMORY();
+            return _PyStatus_NO_MEMORY();
         }
     }
 
@@ -1975,7 +1979,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
 
     *opt_index = _PyOS_optind;
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -1986,21 +1990,21 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions,
 #endif
 
 /* Get warning options from PYTHONWARNINGS environment variable. */
-static _PyInitError
-config_init_env_warnoptions(_PyCoreConfig *config, _PyWstrList *warnoptions)
+static PyStatus
+config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
 {
-    _PyInitError err;
+    PyStatus status;
     /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */
     wchar_t *env = NULL;
-    err = CONFIG_GET_ENV_DUP(config, &env,
+    status = CONFIG_GET_ENV_DUP(config, &env,
                              L"PYTHONWARNINGS", "PYTHONWARNINGS");
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     /* env var is not set or is empty */
     if (env == NULL) {
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
 
@@ -2009,35 +2013,35 @@ config_init_env_warnoptions(_PyCoreConfig *config, _PyWstrList *warnoptions)
          warning != NULL;
          warning = WCSTOK(NULL, L",", &context))
     {
-        if (_PyWstrList_Append(warnoptions, warning) < 0) {
+        status = PyWideStringList_Append(warnoptions, warning);
+        if (_PyStatus_EXCEPTION(status)) {
             PyMem_RawFree(env);
-            return _Py_INIT_NO_MEMORY();
+            return status;
         }
     }
     PyMem_RawFree(env);
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static int
-config_add_warnoption(_PyCoreConfig *config, const wchar_t *option)
+static PyStatus
+config_add_warnoption(PyConfig *config, const wchar_t *option)
 {
-    if (_PyWstrList_Find(&config->warnoptions, option)) {
+    if (_PyWideStringList_Find(&config->warnoptions, option)) {
         /* Already present: do nothing */
-        return 0;
-    }
-    if (_PyWstrList_Append(&config->warnoptions, option)) {
-        return -1;
+        return _PyStatus_OK();
     }
-    return 0;
+    return PyWideStringList_Append(&config->warnoptions, option);
 }
 
 
-static _PyInitError
-config_init_warnoptions(_PyCoreConfig *config,
-                        const _PyWstrList *cmdline_warnoptions,
-                        const _PyWstrList *env_warnoptions)
+static PyStatus
+config_init_warnoptions(PyConfig *config,
+                        const PyWideStringList *cmdline_warnoptions,
+                        const PyWideStringList *env_warnoptions)
 {
+    PyStatus status;
+
     /* The priority order for warnings configuration is (highest precedence
      * first):
      *
@@ -2054,25 +2058,28 @@ config_init_warnoptions(_PyCoreConfig *config,
      */
 
     if (config->dev_mode) {
-        if (config_add_warnoption(config, L"default") < 0) {
-            return _Py_INIT_NO_MEMORY();
+        status = config_add_warnoption(config, L"default");
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     Py_ssize_t i;
-    const _PyWstrList *options;
+    const PyWideStringList *options;
 
     options = env_warnoptions;
     for (i = 0; i < options->length; i++) {
-        if (config_add_warnoption(config, options->items[i]) < 0) {
-            return _Py_INIT_NO_MEMORY();
+        status = config_add_warnoption(config, options->items[i]);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     options = cmdline_warnoptions;
     for (i = 0; i < options->length; i++) {
-        if (config_add_warnoption(config, options->items[i]) < 0) {
-            return _Py_INIT_NO_MEMORY();
+        status = config_add_warnoption(config, options->items[i]);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
@@ -2088,33 +2095,35 @@ config_init_warnoptions(_PyCoreConfig *config,
         else {
             filter = L"default::BytesWarning";
         }
-        if (config_add_warnoption(config, filter) < 0) {
-            return _Py_INIT_NO_MEMORY();
+        status = config_add_warnoption(config, filter);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-config_update_argv(_PyCoreConfig *config, Py_ssize_t opt_index)
+static PyStatus
+config_update_argv(PyConfig *config, Py_ssize_t opt_index)
 {
-    const _PyWstrList *cmdline_argv = &config->argv;
-    _PyWstrList config_argv = _PyWstrList_INIT;
+    const PyWideStringList *cmdline_argv = &config->argv;
+    PyWideStringList config_argv = PyWideStringList_INIT;
 
     /* Copy argv to be able to modify it (to force -c/-m) */
     if (cmdline_argv->length <= opt_index) {
         /* Ensure at least one (empty) argument is seen */
-        if (_PyWstrList_Append(&config_argv, L"") < 0) {
-            return _Py_INIT_NO_MEMORY();
+        PyStatus status = PyWideStringList_Append(&config_argv, L"");
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
     else {
-        _PyWstrList slice;
+        PyWideStringList slice;
         slice.length = cmdline_argv->length - opt_index;
         slice.items = &cmdline_argv->items[opt_index];
-        if (_PyWstrList_Copy(&config_argv, &slice) < 0) {
-            return _Py_INIT_NO_MEMORY();
+        if (_PyWideStringList_Copy(&config_argv, &slice) < 0) {
+            return _PyStatus_NO_MEMORY();
         }
     }
     assert(config_argv.length >= 1);
@@ -2131,109 +2140,108 @@ config_update_argv(_PyCoreConfig *config, Py_ssize_t opt_index)
     if (arg0 != NULL) {
         arg0 = _PyMem_RawWcsdup(arg0);
         if (arg0 == NULL) {
-            _PyWstrList_Clear(&config_argv);
-            return _Py_INIT_NO_MEMORY();
+            _PyWideStringList_Clear(&config_argv);
+            return _PyStatus_NO_MEMORY();
         }
 
         PyMem_RawFree(config_argv.items[0]);
         config_argv.items[0] = arg0;
     }
 
-    _PyWstrList_Clear(&config->argv);
+    _PyWideStringList_Clear(&config->argv);
     config->argv = config_argv;
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-core_read_precmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline)
+static PyStatus
+core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
 {
-    _PyInitError err;
+    PyStatus status;
 
     if (config->parse_argv) {
-        if (_PyWstrList_Copy(&precmdline->argv, &config->argv) < 0) {
-            return _Py_INIT_NO_MEMORY();
+        if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) {
+            return _PyStatus_NO_MEMORY();
         }
     }
 
-    _PyPreConfig preconfig;
+    PyPreConfig preconfig;
     _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig);
 
-    _PyPreConfig_GetCoreConfig(&preconfig, config);
+    _PyPreConfig_GetConfig(&preconfig, config);
 
-    err = _PyPreCmdline_Read(precmdline, &preconfig);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyPreCmdline_Read(precmdline, &preconfig);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    if (_PyPreCmdline_SetCoreConfig(precmdline, config) < 0) {
-        err = _Py_INIT_NO_MEMORY();
-        return err;
+    status = _PyPreCmdline_SetConfig(precmdline, config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-config_read_cmdline(_PyCoreConfig *config)
+static PyStatus
+config_read_cmdline(PyConfig *config)
 {
-    _PyInitError err;
-    _PyWstrList cmdline_warnoptions = _PyWstrList_INIT;
-    _PyWstrList env_warnoptions = _PyWstrList_INIT;
+    PyStatus status;
+    PyWideStringList cmdline_warnoptions = PyWideStringList_INIT;
+    PyWideStringList env_warnoptions = PyWideStringList_INIT;
 
     if (config->parse_argv < 0) {
         config->parse_argv = 1;
     }
 
     if (config->program_name == NULL) {
-        err = config_init_program_name(config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = config_init_program_name(config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     if (config->parse_argv) {
         Py_ssize_t opt_index;
-        err = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
-        if (_Py_INIT_FAILED(err)) {
+        status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index);
+        if (_PyStatus_EXCEPTION(status)) {
             goto done;
         }
 
-        err = config_update_argv(config, opt_index);
-        if (_Py_INIT_FAILED(err)) {
+        status = config_update_argv(config, opt_index);
+        if (_PyStatus_EXCEPTION(status)) {
             goto done;
         }
     }
 
     if (config->use_environment) {
-        err = config_init_env_warnoptions(config, &env_warnoptions);
-        if (_Py_INIT_FAILED(err)) {
+        status = config_init_env_warnoptions(config, &env_warnoptions);
+        if (_PyStatus_EXCEPTION(status)) {
             goto done;
         }
     }
 
-    err = config_init_warnoptions(config,
+    status = config_init_warnoptions(config,
                                   &cmdline_warnoptions, &env_warnoptions);
-    if (_Py_INIT_FAILED(err)) {
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
-    err = _Py_INIT_OK();
+    status = _PyStatus_OK();
 
 done:
-    _PyWstrList_Clear(&cmdline_warnoptions);
-    _PyWstrList_Clear(&env_warnoptions);
-    return err;
+    _PyWideStringList_Clear(&cmdline_warnoptions);
+    _PyWideStringList_Clear(&env_warnoptions);
+    return status;
 }
 
 
-_PyInitError
-_PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args)
+PyStatus
+_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
 {
-    _PyInitError err = _Py_PreInitializeFromCoreConfig(config, args);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _Py_PreInitializeFromConfig(config, args);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     return _PyArgv_AsWstrList(args, &config->argv);
@@ -2242,57 +2250,57 @@ _PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args)
 
 /* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
    if needed to ensure that encodings are properly configured. */
-_PyInitError
-_PyCoreConfig_SetArgv(_PyCoreConfig *config, Py_ssize_t argc, char * const *argv)
+PyStatus
+PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
 {
     _PyArgv args = {
         .argc = argc,
         .use_bytes_argv = 1,
         .bytes_argv = argv,
         .wchar_argv = NULL};
-    return _PyCoreConfig_SetPyArgv(config, &args);
+    return _PyConfig_SetPyArgv(config, &args);
 }
 
 
-_PyInitError
-_PyCoreConfig_SetWideArgv(_PyCoreConfig *config, Py_ssize_t argc, wchar_t * const *argv)
+PyStatus
+PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
 {
     _PyArgv args = {
         .argc = argc,
         .use_bytes_argv = 0,
         .bytes_argv = NULL,
         .wchar_argv = argv};
-    return _PyCoreConfig_SetPyArgv(config, &args);
+    return _PyConfig_SetPyArgv(config, &args);
 }
 
 
-/* Read the configuration into _PyCoreConfig from:
+/* Read the configuration into PyConfig from:
 
    * Command line arguments
    * Environment variables
    * Py_xxx global configuration variables
 
    The only side effects are to modify config and to call _Py_SetArgcArgv(). */
-_PyInitError
-_PyCoreConfig_Read(_PyCoreConfig *config)
+PyStatus
+PyConfig_Read(PyConfig *config)
 {
-    _PyInitError err;
-    _PyWstrList orig_argv = _PyWstrList_INIT;
+    PyStatus status;
+    PyWideStringList orig_argv = PyWideStringList_INIT;
 
-    err = _Py_PreInitializeFromCoreConfig(config, NULL);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _Py_PreInitializeFromConfig(config, NULL);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    _PyCoreConfig_GetGlobalConfig(config);
+    config_get_global_vars(config);
 
-    if (_PyWstrList_Copy(&orig_argv, &config->argv) < 0) {
-        return _Py_INIT_NO_MEMORY();
+    if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) {
+        return _PyStatus_NO_MEMORY();
     }
 
     _PyPreCmdline precmdline = _PyPreCmdline_INIT;
-    err = core_read_precmdline(config, &precmdline);
-    if (_Py_INIT_FAILED(err)) {
+    status = core_read_precmdline(config, &precmdline);
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
@@ -2302,18 +2310,18 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
         config->user_site_directory = 0;
     }
 
-    err = config_read_cmdline(config);
-    if (_Py_INIT_FAILED(err)) {
+    status = config_read_cmdline(config);
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
-    err = config_read(config);
-    if (_Py_INIT_FAILED(err)) {
+    status = config_read(config);
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
     if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) {
-        err = _Py_INIT_NO_MEMORY();
+        status = _PyStatus_NO_MEMORY();
         goto done;
     }
 
@@ -2339,14 +2347,14 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
     assert(config->configure_c_stdio >= 0);
     assert(config->buffered_stdio >= 0);
     assert(config->program_name != NULL);
-    assert(_PyWstrList_CheckConsistency(&config->argv));
+    assert(_PyWideStringList_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));
+    assert(_PyWideStringList_CheckConsistency(&config->xoptions));
+    assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
+    assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
     if (config->_install_importlib) {
-        assert(config->use_module_search_paths != 0);
+        assert(config->module_search_paths_set != 0);
         /* don't check config->module_search_paths */
         assert(config->executable != NULL);
         assert(config->prefix != NULL);
@@ -2367,63 +2375,63 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
     assert(config->_install_importlib >= 0);
     assert(config->pathconfig_warnings >= 0);
 
-    err = _Py_INIT_OK();
+    status = _PyStatus_OK();
 
 done:
-    _PyWstrList_Clear(&orig_argv);
+    _PyWideStringList_Clear(&orig_argv);
     _PyPreCmdline_Clear(&precmdline);
-    return err;
+    return status;
 }
 
 
 PyObject*
 _Py_GetConfigsAsDict(void)
 {
-    PyObject *config = NULL;
+    PyObject *result = NULL;
     PyObject *dict = NULL;
 
-    config = PyDict_New();
-    if (config == NULL) {
+    result = PyDict_New();
+    if (result == NULL) {
         goto error;
     }
 
-    /* global config */
+    /* global result */
     dict = _Py_GetGlobalVariablesAsDict();
     if (dict == NULL) {
         goto error;
     }
-    if (PyDict_SetItemString(config, "global_config", dict) < 0) {
+    if (PyDict_SetItemString(result, "global_config", dict) < 0) {
         goto error;
     }
     Py_CLEAR(dict);
 
     /* pre config */
     PyInterpreterState *interp = _PyInterpreterState_Get();
-    const _PyPreConfig *pre_config = &_PyRuntime.preconfig;
+    const PyPreConfig *pre_config = &_PyRuntime.preconfig;
     dict = _PyPreConfig_AsDict(pre_config);
     if (dict == NULL) {
         goto error;
     }
-    if (PyDict_SetItemString(config, "pre_config", dict) < 0) {
+    if (PyDict_SetItemString(result, "pre_config", dict) < 0) {
         goto error;
     }
     Py_CLEAR(dict);
 
     /* core config */
-    const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp);
-    dict = _PyCoreConfig_AsDict(core_config);
+    const PyConfig *config = &interp->config;
+    dict = config_as_dict(config);
     if (dict == NULL) {
         goto error;
     }
-    if (PyDict_SetItemString(config, "core_config", dict) < 0) {
+    if (PyDict_SetItemString(result, "config", dict) < 0) {
         goto error;
     }
     Py_CLEAR(dict);
 
-    return config;
+    return result;
 
 error:
-    Py_XDECREF(config);
+    Py_XDECREF(result);
     Py_XDECREF(dict);
     return NULL;
 }
diff --git a/Python/pathconfig.c b/Python/pathconfig.c
index bbf29b2fa598..ec67405a28d0 100644
--- a/Python/pathconfig.c
+++ b/Python/pathconfig.c
@@ -2,7 +2,7 @@
 
 #include "Python.h"
 #include "osdefs.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_fileutils.h"
 #include "pycore_pathconfig.h"
 #include "pycore_pymem.h"
@@ -34,7 +34,7 @@ copy_wstr(wchar_t **dst, const wchar_t *src)
 
 
 static void
-_PyPathConfig_Clear(_PyPathConfig *config)
+pathconfig_clear(_PyPathConfig *config)
 {
     /* _PyMem_SetDefaultAllocator() is needed to get a known memory allocator,
        since Py_SetPath(), Py_SetPythonHome() and Py_SetProgramName() can be
@@ -63,12 +63,11 @@ _PyPathConfig_Clear(_PyPathConfig *config)
 }
 
 
-/* Calculate the path configuration: initialize path_config from core_config */
-static _PyInitError
-_PyPathConfig_Calculate(_PyPathConfig *path_config,
-                        const _PyCoreConfig *core_config)
+/* Calculate the path configuration: initialize pathconfig from config */
+static PyStatus
+pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config)
 {
-    _PyInitError err;
+    PyStatus status;
     _PyPathConfig new_config = _PyPathConfig_INIT;
 
     PyMemAllocatorEx old_alloc;
@@ -76,40 +75,40 @@ _PyPathConfig_Calculate(_PyPathConfig *path_config,
 
     /* Calculate program_full_path, prefix, exec_prefix,
        dll_path (Windows), and module_search_path */
-    err = _PyPathConfig_Calculate_impl(&new_config, core_config);
-    if (_Py_INIT_FAILED(err)) {
-        goto err;
+    status = _PyPathConfig_Calculate(&new_config, config);
+    if (_PyStatus_EXCEPTION(status)) {
+        goto error;
     }
 
-    /* Copy home and program_name from core_config */
-    if (copy_wstr(&new_config.home, core_config->home) < 0) {
-        err = _Py_INIT_NO_MEMORY();
-        goto err;
+    /* Copy home and program_name from config */
+    if (copy_wstr(&new_config.home, config->home) < 0) {
+        status = _PyStatus_NO_MEMORY();
+        goto error;
     }
-    if (copy_wstr(&new_config.program_name, core_config->program_name) < 0) {
-        err = _Py_INIT_NO_MEMORY();
-        goto err;
+    if (copy_wstr(&new_config.program_name, config->program_name) < 0) {
+        status = _PyStatus_NO_MEMORY();
+        goto error;
     }
 
-    _PyPathConfig_Clear(path_config);
-    *path_config = new_config;
+    pathconfig_clear(pathconfig);
+    *pathconfig = new_config;
 
-    err = _Py_INIT_OK();
+    status = _PyStatus_OK();
     goto done;
 
-err:
-    _PyPathConfig_Clear(&new_config);
+error:
+    pathconfig_clear(&new_config);
 
 done:
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
-    return err;
+    return status;
 }
 
 
-_PyInitError
+PyStatus
 _PyPathConfig_SetGlobal(const _PyPathConfig *config)
 {
-    _PyInitError err;
+    PyStatus status;
     _PyPathConfig new_config = _PyPathConfig_INIT;
 
     PyMemAllocatorEx old_alloc;
@@ -118,8 +117,8 @@ _PyPathConfig_SetGlobal(const _PyPathConfig *config)
 #define COPY_ATTR(ATTR) \
     do { \
         if (copy_wstr(&new_config.ATTR, config->ATTR) < 0) { \
-            _PyPathConfig_Clear(&new_config); \
-            err = _Py_INIT_NO_MEMORY(); \
+            pathconfig_clear(&new_config); \
+            status = _PyStatus_NO_MEMORY(); \
             goto done; \
         } \
     } while (0)
@@ -134,15 +133,15 @@ _PyPathConfig_SetGlobal(const _PyPathConfig *config)
     COPY_ATTR(program_name);
     COPY_ATTR(home);
 
-    _PyPathConfig_Clear(&_Py_path_config);
+    pathconfig_clear(&_Py_path_config);
     /* Steal new_config strings; don't clear new_config */
     _Py_path_config = new_config;
 
-    err = _Py_INIT_OK();
+    status = _PyStatus_OK();
 
 done:
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
-    return err;
+    return status;
 }
 
 
@@ -152,14 +151,14 @@ _PyPathConfig_ClearGlobal(void)
     PyMemAllocatorEx old_alloc;
     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 
-    _PyPathConfig_Clear(&_Py_path_config);
+    pathconfig_clear(&_Py_path_config);
 
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 }
 
 
 static wchar_t*
-_PyWstrList_Join(const _PyWstrList *list, wchar_t sep)
+_PyWideStringList_Join(const PyWideStringList *list, wchar_t sep)
 {
     size_t len = 1;   /* NUL terminator */
     for (Py_ssize_t i=0; i < list->length; i++) {
@@ -189,70 +188,69 @@ _PyWstrList_Join(const _PyWstrList *list, wchar_t sep)
 }
 
 
-/* Set the global path configuration from core_config. */
-_PyInitError
-_PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config)
+/* Set the global path configuration from config. */
+PyStatus
+_PyConfig_SetPathConfig(const PyConfig *config)
 {
     PyMemAllocatorEx old_alloc;
     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 
-    _PyInitError err;
-    _PyPathConfig path_config = _PyPathConfig_INIT;
+    PyStatus status;
+    _PyPathConfig pathconfig = _PyPathConfig_INIT;
 
-    path_config.module_search_path = _PyWstrList_Join(&core_config->module_search_paths, DELIM);
-    if (path_config.module_search_path == NULL) {
+    pathconfig.module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM);
+    if (pathconfig.module_search_path == NULL) {
         goto no_memory;
     }
 
-    if (copy_wstr(&path_config.program_full_path, core_config->executable) < 0) {
+    if (copy_wstr(&pathconfig.program_full_path, config->executable) < 0) {
         goto no_memory;
     }
-    if (copy_wstr(&path_config.prefix, core_config->prefix) < 0) {
+    if (copy_wstr(&pathconfig.prefix, config->prefix) < 0) {
         goto no_memory;
     }
-    if (copy_wstr(&path_config.exec_prefix, core_config->exec_prefix) < 0) {
+    if (copy_wstr(&pathconfig.exec_prefix, config->exec_prefix) < 0) {
         goto no_memory;
     }
 #ifdef MS_WINDOWS
-    path_config.dll_path = _Py_GetDLLPath();
-    if (path_config.dll_path == NULL) {
+    pathconfig.dll_path = _Py_GetDLLPath();
+    if (pathconfig.dll_path == NULL) {
         goto no_memory;
     }
 #endif
-    if (copy_wstr(&path_config.program_name, core_config->program_name) < 0) {
+    if (copy_wstr(&pathconfig.program_name, config->program_name) < 0) {
         goto no_memory;
     }
-    if (copy_wstr(&path_config.home, core_config->home) < 0) {
+    if (copy_wstr(&pathconfig.home, config->home) < 0) {
         goto no_memory;
     }
 
-    err = _PyPathConfig_SetGlobal(&path_config);
-    if (_Py_INIT_FAILED(err)) {
+    status = _PyPathConfig_SetGlobal(&pathconfig);
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
-    err = _Py_INIT_OK();
+    status = _PyStatus_OK();
     goto done;
 
 no_memory:
-    err = _Py_INIT_NO_MEMORY();
+    status = _PyStatus_NO_MEMORY();
 
 done:
-    _PyPathConfig_Clear(&path_config);
+    pathconfig_clear(&pathconfig);
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
-    return err;
+    return status;
 }
 
 
-static _PyInitError
-core_config_init_module_search_paths(_PyCoreConfig *config,
-                                     _PyPathConfig *path_config)
+static PyStatus
+config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig)
 {
-    assert(!config->use_module_search_paths);
+    assert(!config->module_search_paths_set);
 
-    _PyWstrList_Clear(&config->module_search_paths);
+    _PyWideStringList_Clear(&config->module_search_paths);
 
-    const wchar_t *sys_path = path_config->module_search_path;
+    const wchar_t *sys_path = pathconfig->module_search_path;
     const wchar_t delim = DELIM;
     const wchar_t *p = sys_path;
     while (1) {
@@ -264,15 +262,15 @@ core_config_init_module_search_paths(_PyCoreConfig *config,
         size_t path_len = (p - sys_path);
         wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t));
         if (path == NULL) {
-            return _Py_INIT_NO_MEMORY();
+            return _PyStatus_NO_MEMORY();
         }
         memcpy(path, sys_path, path_len * sizeof(wchar_t));
         path[path_len] = L'\0';
 
-        int res = _PyWstrList_Append(&config->module_search_paths, path);
+        PyStatus status = PyWideStringList_Append(&config->module_search_paths, path);
         PyMem_RawFree(path);
-        if (res < 0) {
-            return _Py_INIT_NO_MEMORY();
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
         if (*p == '\0') {
@@ -280,96 +278,96 @@ core_config_init_module_search_paths(_PyCoreConfig *config,
         }
         sys_path = p + 1;
     }
-    config->use_module_search_paths = 1;
-    return _Py_INIT_OK();
+    config->module_search_paths_set = 1;
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-_PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config)
+static PyStatus
+config_calculate_pathconfig(PyConfig *config)
 {
-    _PyPathConfig path_config = _PyPathConfig_INIT;
-    _PyInitError err;
+    _PyPathConfig pathconfig = _PyPathConfig_INIT;
+    PyStatus status;
 
-    err = _PyPathConfig_Calculate(&path_config, config);
-    if (_Py_INIT_FAILED(err)) {
+    status = pathconfig_calculate(&pathconfig, config);
+    if (_PyStatus_EXCEPTION(status)) {
         goto error;
     }
 
-    if (!config->use_module_search_paths) {
-        err = core_config_init_module_search_paths(config, &path_config);
-        if (_Py_INIT_FAILED(err)) {
+    if (!config->module_search_paths_set) {
+        status = config_init_module_search_paths(config, &pathconfig);
+        if (_PyStatus_EXCEPTION(status)) {
             goto error;
         }
     }
 
     if (config->executable == NULL) {
         if (copy_wstr(&config->executable,
-                      path_config.program_full_path) < 0) {
+                      pathconfig.program_full_path) < 0) {
             goto no_memory;
         }
     }
 
     if (config->prefix == NULL) {
-        if (copy_wstr(&config->prefix, path_config.prefix) < 0) {
+        if (copy_wstr(&config->prefix, pathconfig.prefix) < 0) {
             goto no_memory;
         }
     }
 
     if (config->exec_prefix == NULL) {
         if (copy_wstr(&config->exec_prefix,
-                      path_config.exec_prefix) < 0) {
+                      pathconfig.exec_prefix) < 0) {
             goto no_memory;
         }
     }
 
-    if (path_config.isolated != -1) {
-        config->isolated = path_config.isolated;
+    if (pathconfig.isolated != -1) {
+        config->isolated = pathconfig.isolated;
     }
-    if (path_config.site_import != -1) {
-        config->site_import = path_config.site_import;
+    if (pathconfig.site_import != -1) {
+        config->site_import = pathconfig.site_import;
     }
 
-    _PyPathConfig_Clear(&path_config);
-    return _Py_INIT_OK();
+    pathconfig_clear(&pathconfig);
+    return _PyStatus_OK();
 
 no_memory:
-    err = _Py_INIT_NO_MEMORY();
+    status = _PyStatus_NO_MEMORY();
 
 error:
-    _PyPathConfig_Clear(&path_config);
-    return err;
+    pathconfig_clear(&pathconfig);
+    return status;
 }
 
 
-_PyInitError
-_PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
+PyStatus
+_PyConfig_InitPathConfig(PyConfig *config)
 {
     /* Do we need to calculate the path? */
-    if (!config->use_module_search_paths
+    if (!config->module_search_paths_set
         || (config->executable == NULL)
         || (config->prefix == NULL)
         || (config->exec_prefix == NULL))
     {
-        _PyInitError err = _PyCoreConfig_CalculatePathConfig(config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        PyStatus status = config_calculate_pathconfig(config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     if (config->base_prefix == NULL) {
         if (copy_wstr(&config->base_prefix, config->prefix) < 0) {
-            return _Py_INIT_NO_MEMORY();
+            return _PyStatus_NO_MEMORY();
         }
     }
 
     if (config->base_exec_prefix == NULL) {
         if (copy_wstr(&config->base_exec_prefix,
                       config->exec_prefix) < 0) {
-            return _Py_INIT_NO_MEMORY();
+            return _PyStatus_NO_MEMORY();
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -381,26 +379,26 @@ pathconfig_global_init(void)
         return;
     }
 
-    _PyInitError err;
-    _PyCoreConfig config;
-    _PyCoreConfig_InitCompatConfig(&config);
+    PyStatus status;
+    PyConfig config;
+    _PyConfig_InitCompatConfig(&config);
 
-    err = _PyCoreConfig_Read(&config);
-    if (_Py_INIT_FAILED(err)) {
+    status = PyConfig_Read(&config);
+    if (_PyStatus_EXCEPTION(status)) {
         goto error;
     }
 
-    err = _PyCoreConfig_SetPathConfig(&config);
-    if (_Py_INIT_FAILED(err)) {
+    status = _PyConfig_SetPathConfig(&config);
+    if (_PyStatus_EXCEPTION(status)) {
         goto error;
     }
 
-    _PyCoreConfig_Clear(&config);
+    PyConfig_Clear(&config);
     return;
 
 error:
-    _PyCoreConfig_Clear(&config);
-    _Py_ExitInitError(err);
+    PyConfig_Clear(&config);
+    Py_ExitStatusException(status);
 }
 
 
@@ -410,7 +408,7 @@ void
 Py_SetPath(const wchar_t *path)
 {
     if (path == NULL) {
-        _PyPathConfig_Clear(&_Py_path_config);
+        pathconfig_clear(&_Py_path_config);
         return;
     }
 
@@ -437,7 +435,7 @@ Py_SetPath(const wchar_t *path)
     new_config.program_name = _Py_path_config.program_name;
     _Py_path_config.program_name = NULL;
 
-    _PyPathConfig_Clear(&_Py_path_config);
+    pathconfig_clear(&_Py_path_config);
     _Py_path_config = new_config;
 
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
@@ -569,9 +567,9 @@ Py_GetProgramName(void)
    Raise an exception and return -1 on error.
    */
 int
-_PyPathConfig_ComputeSysPath0(const _PyWstrList *argv, PyObject **path0_p)
+_PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p)
 {
-    assert(_PyWstrList_CheckConsistency(argv));
+    assert(_PyWideStringList_CheckConsistency(argv));
 
     if (argv->length == 0) {
         /* Leave sys.path unchanged if sys.argv is empty */
diff --git a/Python/preconfig.c b/Python/preconfig.c
index a6d1346eb4e1..8be6533eace0 100644
--- a/Python/preconfig.c
+++ b/Python/preconfig.c
@@ -1,5 +1,5 @@
 #include "Python.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_getopt.h"
 #include "pycore_pystate.h"   /* _PyRuntime_Initialize() */
 #include <locale.h>       /* setlocale() */
@@ -7,8 +7,13 @@
 
 #define DECODE_LOCALE_ERR(NAME, LEN) \
     (((LEN) == -2) \
-     ? _Py_INIT_ERR("cannot decode " NAME) \
-     : _Py_INIT_NO_MEMORY())
+     ? _PyStatus_ERR("cannot decode " NAME) \
+     : _PyStatus_NO_MEMORY())
+
+
+/* Forward declarations */
+static void
+preconfig_copy(PyPreConfig *config, const PyPreConfig *config2);
 
 
 /* --- File system encoding/errors -------------------------------- */
@@ -67,22 +72,22 @@ _Py_SetFileSystemEncoding(const char *encoding, const char *errors)
 /* --- _PyArgv ---------------------------------------------------- */
 
 /* Decode bytes_argv using Py_DecodeLocale() */
-_PyInitError
-_PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list)
+PyStatus
+_PyArgv_AsWstrList(const _PyArgv *args, PyWideStringList *list)
 {
-    _PyWstrList wargv = _PyWstrList_INIT;
+    PyWideStringList wargv = PyWideStringList_INIT;
     if (args->use_bytes_argv) {
         size_t size = sizeof(wchar_t*) * args->argc;
         wargv.items = (wchar_t **)PyMem_RawMalloc(size);
         if (wargv.items == NULL) {
-            return _Py_INIT_NO_MEMORY();
+            return _PyStatus_NO_MEMORY();
         }
 
         for (Py_ssize_t i = 0; i < args->argc; i++) {
             size_t len;
             wchar_t *arg = Py_DecodeLocale(args->bytes_argv[i], &len);
             if (arg == NULL) {
-                _PyWstrList_Clear(&wargv);
+                _PyWideStringList_Clear(&wargv);
                 return DECODE_LOCALE_ERR("command line arguments",
                                          (Py_ssize_t)len);
             }
@@ -90,17 +95,17 @@ _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list)
             wargv.length++;
         }
 
-        _PyWstrList_Clear(list);
+        _PyWideStringList_Clear(list);
         *list = wargv;
     }
     else {
         wargv.length = args->argc;
         wargv.items = (wchar_t **)args->wchar_argv;
-        if (_PyWstrList_Copy(list, &wargv) < 0) {
-            return _Py_INIT_NO_MEMORY();
+        if (_PyWideStringList_Copy(list, &wargv) < 0) {
+            return _PyStatus_NO_MEMORY();
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -109,12 +114,12 @@ _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list)
 void
 _PyPreCmdline_Clear(_PyPreCmdline *cmdline)
 {
-    _PyWstrList_Clear(&cmdline->argv);
-    _PyWstrList_Clear(&cmdline->xoptions);
+    _PyWideStringList_Clear(&cmdline->argv);
+    _PyWideStringList_Clear(&cmdline->xoptions);
 }
 
 
-_PyInitError
+PyStatus
 _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args)
 {
     return _PyArgv_AsWstrList(args, &cmdline->argv);
@@ -122,7 +127,7 @@ _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args)
 
 
 static void
-_PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config)
+precmdline_get_preconfig(_PyPreCmdline *cmdline, const PyPreConfig *config)
 {
 #define COPY_ATTR(ATTR) \
     if (config->ATTR != -1) { \
@@ -138,7 +143,7 @@ _PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config)
 
 
 static void
-_PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config)
+precmdline_set_preconfig(const _PyPreCmdline *cmdline, PyPreConfig *config)
 {
 #define COPY_ATTR(ATTR) \
     config->ATTR = cmdline->ATTR
@@ -151,33 +156,34 @@ _PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config)
 }
 
 
-int
-_PyPreCmdline_SetCoreConfig(const _PyPreCmdline *cmdline, _PyCoreConfig *config)
+PyStatus
+_PyPreCmdline_SetConfig(const _PyPreCmdline *cmdline, PyConfig *config)
 {
 #define COPY_ATTR(ATTR) \
     config->ATTR = cmdline->ATTR
 
-    if (_PyWstrList_Extend(&config->xoptions, &cmdline->xoptions) < 0) {
-        return -1;
+    PyStatus status = _PyWideStringList_Extend(&config->xoptions, &cmdline->xoptions);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     COPY_ATTR(isolated);
     COPY_ATTR(use_environment);
     COPY_ATTR(dev_mode);
-    return 0;
+    return _PyStatus_OK();
 
 #undef COPY_ATTR
 }
 
 
 /* Parse the command line arguments */
-static _PyInitError
+static PyStatus
 precmdline_parse_cmdline(_PyPreCmdline *cmdline)
 {
-    const _PyWstrList *argv = &cmdline->argv;
+    const PyWideStringList *argv = &cmdline->argv;
 
     _PyOS_ResetGetOpt();
-    /* Don't log parsing errors into stderr here: _PyCoreConfig_Read()
+    /* Don't log parsing errors into stderr here: PyConfig_Read()
        is responsible for that */
     _PyOS_opterr = 0;
     do {
@@ -199,32 +205,34 @@ precmdline_parse_cmdline(_PyPreCmdline *cmdline)
 
         case 'X':
         {
-            if (_PyWstrList_Append(&cmdline->xoptions, _PyOS_optarg) < 0) {
-                return _Py_INIT_NO_MEMORY();
+            PyStatus status = PyWideStringList_Append(&cmdline->xoptions,
+                                                      _PyOS_optarg);
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
             break;
         }
 
         default:
             /* ignore other argument:
-               handled by _PyCoreConfig_Read() */
+               handled by PyConfig_Read() */
             break;
         }
     } while (1);
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-_PyInitError
-_PyPreCmdline_Read(_PyPreCmdline *cmdline, const _PyPreConfig *preconfig)
+PyStatus
+_PyPreCmdline_Read(_PyPreCmdline *cmdline, const PyPreConfig *preconfig)
 {
-    _PyPreCmdline_GetPreConfig(cmdline, preconfig);
+    precmdline_get_preconfig(cmdline, preconfig);
 
     if (preconfig->parse_argv) {
-        _PyInitError err = precmdline_parse_cmdline(cmdline);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        PyStatus status = precmdline_parse_cmdline(cmdline);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
@@ -254,15 +262,15 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline, const _PyPreConfig *preconfig)
     assert(cmdline->isolated >= 0);
     assert(cmdline->dev_mode >= 0);
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-/* --- _PyPreConfig ----------------------------------------------- */
+/* --- PyPreConfig ----------------------------------------------- */
 
 
 void
-_PyPreConfig_InitCompatConfig(_PyPreConfig *config)
+_PyPreConfig_InitCompatConfig(PyPreConfig *config)
 {
     memset(config, 0, sizeof(*config));
 
@@ -291,7 +299,7 @@ _PyPreConfig_InitCompatConfig(_PyPreConfig *config)
 
 
 void
-_PyPreConfig_InitPythonConfig(_PyPreConfig *config)
+PyPreConfig_InitPythonConfig(PyPreConfig *config)
 {
     _PyPreConfig_InitCompatConfig(config);
 
@@ -312,7 +320,7 @@ _PyPreConfig_InitPythonConfig(_PyPreConfig *config)
 
 
 void
-_PyPreConfig_InitIsolatedConfig(_PyPreConfig *config)
+PyPreConfig_InitIsolatedConfig(PyPreConfig *config)
 {
     _PyPreConfig_InitCompatConfig(config);
 
@@ -329,37 +337,37 @@ _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config)
 
 
 void
-_PyPreConfig_InitFromPreConfig(_PyPreConfig *config,
-                               const _PyPreConfig *config2)
+_PyPreConfig_InitFromPreConfig(PyPreConfig *config,
+                               const PyPreConfig *config2)
 {
-    _PyPreConfig_InitCompatConfig(config);
-    _PyPreConfig_Copy(config, config2);
+    PyPreConfig_InitPythonConfig(config);
+    preconfig_copy(config, config2);
 }
 
 
 void
-_PyPreConfig_InitFromCoreConfig(_PyPreConfig *config,
-                                const _PyCoreConfig *coreconfig)
+_PyPreConfig_InitFromConfig(PyPreConfig *preconfig, const PyConfig *config)
 {
-    _PyConfigInitEnum config_init = (_PyConfigInitEnum)coreconfig->_config_init;
+    _PyConfigInitEnum config_init = (_PyConfigInitEnum)config->_config_init;
     switch (config_init) {
     case _PyConfig_INIT_PYTHON:
-        _PyPreConfig_InitPythonConfig(config);
+        PyPreConfig_InitPythonConfig(preconfig);
         break;
     case _PyConfig_INIT_ISOLATED:
-        _PyPreConfig_InitIsolatedConfig(config);
+        PyPreConfig_InitIsolatedConfig(preconfig);
         break;
     case _PyConfig_INIT_COMPAT:
     default:
-        _PyPreConfig_InitCompatConfig(config);
+        _PyPreConfig_InitCompatConfig(preconfig);
     }
-    _PyPreConfig_GetCoreConfig(config, coreconfig);
+    _PyPreConfig_GetConfig(preconfig, config);
 }
 
 
-void
-_PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2)
+static void
+preconfig_copy(PyPreConfig *config, const PyPreConfig *config2)
 {
+    assert(config2->_config_version == _Py_CONFIG_VERSION);
 #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
 
     COPY_ATTR(_config_init);
@@ -381,7 +389,7 @@ _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2)
 
 
 PyObject*
-_PyPreConfig_AsDict(const _PyPreConfig *config)
+_PyPreConfig_AsDict(const PyPreConfig *config)
 {
     PyObject *dict;
 
@@ -427,12 +435,11 @@ _PyPreConfig_AsDict(const _PyPreConfig *config)
 
 
 void
-_PyPreConfig_GetCoreConfig(_PyPreConfig *config,
-                            const _PyCoreConfig *core_config)
+_PyPreConfig_GetConfig(PyPreConfig *preconfig, const PyConfig *config)
 {
 #define COPY_ATTR(ATTR) \
-    if (core_config->ATTR != -1) { \
-        config->ATTR = core_config->ATTR; \
+    if (config->ATTR != -1) { \
+        preconfig->ATTR = config->ATTR; \
     }
 
     COPY_ATTR(parse_argv);
@@ -445,7 +452,7 @@ _PyPreConfig_GetCoreConfig(_PyPreConfig *config,
 
 
 static void
-_PyPreConfig_GetGlobalConfig(_PyPreConfig *config)
+preconfig_get_global_vars(PyPreConfig *config)
 {
     if (config->_config_init != _PyConfig_INIT_COMPAT) {
         /* Python and Isolated configuration ignore global variables */
@@ -476,7 +483,7 @@ _PyPreConfig_GetGlobalConfig(_PyPreConfig *config)
 
 
 static void
-_PyPreConfig_SetGlobalConfig(const _PyPreConfig *config)
+preconfig_set_global_vars(const PyPreConfig *config)
 {
 #define COPY_FLAG(ATTR, VAR) \
     if (config->ATTR >= 0) { \
@@ -555,7 +562,7 @@ _Py_get_env_flag(int use_environment, int *flag, const char *name)
 
 
 const wchar_t*
-_Py_get_xoption(const _PyWstrList *xoptions, const wchar_t *name)
+_Py_get_xoption(const PyWideStringList *xoptions, const wchar_t *name)
 {
     for (Py_ssize_t i=0; i < xoptions->length; i++) {
         const wchar_t *option = xoptions->items[i];
@@ -575,8 +582,8 @@ _Py_get_xoption(const _PyWstrList *xoptions, const wchar_t *name)
 }
 
 
-static _PyInitError
-preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline)
+static PyStatus
+preconfig_init_utf8_mode(PyPreConfig *config, const _PyPreCmdline *cmdline)
 {
 #ifdef MS_WINDOWS
     if (config->legacy_windows_fs_encoding) {
@@ -585,7 +592,7 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline)
 #endif
 
     if (config->utf8_mode >= 0) {
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     const wchar_t *xopt;
@@ -601,13 +608,13 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline)
                 config->utf8_mode = 0;
             }
             else {
-                return _Py_INIT_ERR("invalid -X utf8 option value");
+                return _PyStatus_ERR("invalid -X utf8 option value");
             }
         }
         else {
             config->utf8_mode = 1;
         }
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     const char *opt = _Py_GetEnv(config->use_environment, "PYTHONUTF8");
@@ -619,10 +626,10 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline)
             config->utf8_mode = 0;
         }
         else {
-            return _Py_INIT_ERR("invalid PYTHONUTF8 environment "
+            return _PyStatus_ERR("invalid PYTHONUTF8 environment "
                                 "variable value");
         }
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
 
@@ -642,12 +649,12 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline)
     if (config->utf8_mode < 0) {
         config->utf8_mode = 0;
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
 static void
-preconfig_init_coerce_c_locale(_PyPreConfig *config)
+preconfig_init_coerce_c_locale(PyPreConfig *config)
 {
     if (!config->configure_locale) {
         config->coerce_c_locale = 0;
@@ -693,8 +700,8 @@ preconfig_init_coerce_c_locale(_PyPreConfig *config)
 }
 
 
-static _PyInitError
-preconfig_init_allocator(_PyPreConfig *config)
+static PyStatus
+preconfig_init_allocator(PyPreConfig *config)
 {
     if (config->allocator == PYMEM_ALLOCATOR_NOT_SET) {
         /* bpo-34247. The PYTHONMALLOC environment variable has the priority
@@ -705,7 +712,7 @@ preconfig_init_allocator(_PyPreConfig *config)
         if (envvar) {
             PyMemAllocatorName name;
             if (_PyMem_GetAllocatorName(envvar, &name) < 0) {
-                return _Py_INIT_ERR("PYTHONMALLOC: unknown allocator");
+                return _PyStatus_ERR("PYTHONMALLOC: unknown allocator");
             }
             config->allocator = (int)name;
         }
@@ -714,21 +721,21 @@ preconfig_init_allocator(_PyPreConfig *config)
     if (config->dev_mode && config->allocator == PYMEM_ALLOCATOR_NOT_SET) {
         config->allocator = PYMEM_ALLOCATOR_DEBUG;
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline)
+static PyStatus
+preconfig_read(PyPreConfig *config, _PyPreCmdline *cmdline)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    err = _PyPreCmdline_Read(cmdline, config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyPreCmdline_Read(cmdline, config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    _PyPreCmdline_SetPreConfig(cmdline, config);
+    precmdline_set_preconfig(cmdline, config);
 
     /* legacy_windows_fs_encoding, coerce_c_locale, utf8_mode */
 #ifdef MS_WINDOWS
@@ -739,15 +746,15 @@ preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline)
 
     preconfig_init_coerce_c_locale(config);
 
-    err = preconfig_init_utf8_mode(config, cmdline);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = preconfig_init_utf8_mode(config, cmdline);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     /* allocator */
-    err = preconfig_init_allocator(config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = preconfig_init_allocator(config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     assert(config->coerce_c_locale >= 0);
@@ -760,7 +767,7 @@ preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline)
     assert(config->use_environment >= 0);
     assert(config->dev_mode >= 0);
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -770,30 +777,30 @@ preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline)
    - environment variables
    - Py_xxx global configuration variables
    - the LC_CTYPE locale */
-_PyInitError
-_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
+PyStatus
+_PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    err = _PyRuntime_Initialize();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyRuntime_Initialize();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    _PyPreConfig_GetGlobalConfig(config);
+    preconfig_get_global_vars(config);
 
     /* Copy LC_CTYPE locale, since it's modified later */
     const char *loc = setlocale(LC_CTYPE, NULL);
     if (loc == NULL) {
-        return _Py_INIT_ERR("failed to LC_CTYPE locale");
+        return _PyStatus_ERR("failed to LC_CTYPE locale");
     }
     char *init_ctype_locale = _PyMem_RawStrdup(loc);
     if (init_ctype_locale == NULL) {
-        return _Py_INIT_NO_MEMORY();
+        return _PyStatus_NO_MEMORY();
     }
 
     /* Save the config to be able to restore it if encodings change */
-    _PyPreConfig save_config;
+    PyPreConfig save_config;
     _PyPreConfig_InitFromPreConfig(&save_config, config);
 
     /* Set LC_CTYPE to the user preferred locale */
@@ -808,8 +815,8 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
 #endif
 
     if (args) {
-        err = _PyPreCmdline_SetArgv(&cmdline, args);
-        if (_Py_INIT_FAILED(err)) {
+        status = _PyPreCmdline_SetArgv(&cmdline, args);
+        if (_PyStatus_EXCEPTION(status)) {
             goto done;
         }
     }
@@ -823,7 +830,7 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
         /* Watchdog to prevent an infinite loop */
         loops++;
         if (loops == 3) {
-            err = _Py_INIT_ERR("Encoding changed twice while "
+            status = _PyStatus_ERR("Encoding changed twice while "
                                "reading the configuration");
             goto done;
         }
@@ -835,8 +842,8 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
         Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding;
 #endif
 
-        err = preconfig_read(config, &cmdline);
-        if (_Py_INIT_FAILED(err)) {
+        status = preconfig_read(config, &cmdline);
+        if (_PyStatus_EXCEPTION(status)) {
             goto done;
         }
 
@@ -877,14 +884,14 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
            just keep UTF-8 Mode value. */
         int new_utf8_mode = config->utf8_mode;
         int new_coerce_c_locale = config->coerce_c_locale;
-        _PyPreConfig_Copy(config, &save_config);
+        preconfig_copy(config, &save_config);
         config->utf8_mode = new_utf8_mode;
         config->coerce_c_locale = new_coerce_c_locale;
 
         /* The encoding changed: read again the configuration
            with the new encoding */
     }
-    err = _Py_INIT_OK();
+    status = _PyStatus_OK();
 
 done:
     if (init_ctype_locale != NULL) {
@@ -896,7 +903,7 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
     Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding;
 #endif
     _PyPreCmdline_Clear(&cmdline);
-    return err;
+    return status;
 }
 
 
@@ -912,26 +919,26 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
 
    Do nothing if called after Py_Initialize(): ignore the new
    pre-configuration. */
-_PyInitError
-_PyPreConfig_Write(const _PyPreConfig *src_config)
+PyStatus
+_PyPreConfig_Write(const PyPreConfig *src_config)
 {
-    _PyPreConfig config;
+    PyPreConfig config;
     _PyPreConfig_InitFromPreConfig(&config, src_config);
 
     if (_PyRuntime.core_initialized) {
         /* bpo-34008: Calling this functions after Py_Initialize() ignores
            the new configuration. */
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     PyMemAllocatorName name = (PyMemAllocatorName)config.allocator;
     if (name != PYMEM_ALLOCATOR_NOT_SET) {
         if (_PyMem_SetupAllocators(name) < 0) {
-            return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator");
+            return _PyStatus_ERR("Unknown PYTHONMALLOC allocator");
         }
     }
 
-    _PyPreConfig_SetGlobalConfig(&config);
+    preconfig_set_global_vars(&config);
 
     if (config.configure_locale) {
         if (config.coerce_c_locale) {
@@ -946,7 +953,7 @@ _PyPreConfig_Write(const _PyPreConfig *src_config)
     }
 
     /* Write the new pre-configuration into _PyRuntime */
-    _PyPreConfig_Copy(&_PyRuntime.preconfig, &config);
+    preconfig_copy(&_PyRuntime.preconfig, &config);
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 9880c0d624d5..10a28813faa8 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -6,7 +6,7 @@
 #undef Yield   /* undefine macro conflicting with <winbase.h> */
 #include "pycore_ceval.h"
 #include "pycore_context.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_fileutils.h"
 #include "pycore_hamt.h"
 #include "pycore_pathconfig.h"
@@ -60,10 +60,10 @@ extern "C" {
 extern grammar _PyParser_Grammar; /* From graminit.c */
 
 /* Forward */
-static _PyInitError add_main_module(PyInterpreterState *interp);
-static _PyInitError init_import_size(void);
-static _PyInitError init_sys_streams(PyInterpreterState *interp);
-static _PyInitError init_signals(void);
+static PyStatus add_main_module(PyInterpreterState *interp);
+static PyStatus init_import_size(void);
+static PyStatus init_sys_streams(PyInterpreterState *interp);
+static PyStatus init_signals(void);
 static void call_py_exitfuncs(PyInterpreterState *);
 static void wait_for_thread_shutdown(void);
 static void call_ll_exitfuncs(_PyRuntimeState *runtime);
@@ -72,7 +72,7 @@ int _Py_UnhandledKeyboardInterrupt = 0;
 _PyRuntimeState _PyRuntime = _PyRuntimeState_INIT;
 static int runtime_initialized = 0;
 
-_PyInitError
+PyStatus
 _PyRuntime_Initialize(void)
 {
     /* XXX We only initialize once in the process, which aligns with
@@ -82,7 +82,7 @@ _PyRuntime_Initialize(void)
        This is because the runtime state is not properly finalized
        currently. */
     if (runtime_initialized) {
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
     runtime_initialized = 1;
 
@@ -145,58 +145,58 @@ Py_IsInitialized(void)
 
 */
 
-static _PyInitError
+static PyStatus
 init_importlib(PyInterpreterState *interp, PyObject *sysmod)
 {
     PyObject *importlib;
     PyObject *impmod;
     PyObject *value;
-    int verbose = interp->core_config.verbose;
+    int verbose = interp->config.verbose;
 
     /* Import _importlib through its frozen version, _frozen_importlib. */
     if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) {
-        return _Py_INIT_ERR("can't import _frozen_importlib");
+        return _PyStatus_ERR("can't import _frozen_importlib");
     }
     else if (verbose) {
         PySys_FormatStderr("import _frozen_importlib # frozen\n");
     }
     importlib = PyImport_AddModule("_frozen_importlib");
     if (importlib == NULL) {
-        return _Py_INIT_ERR("couldn't get _frozen_importlib from sys.modules");
+        return _PyStatus_ERR("couldn't get _frozen_importlib from sys.modules");
     }
     interp->importlib = importlib;
     Py_INCREF(interp->importlib);
 
     interp->import_func = PyDict_GetItemString(interp->builtins, "__import__");
     if (interp->import_func == NULL)
-        return _Py_INIT_ERR("__import__ not found");
+        return _PyStatus_ERR("__import__ not found");
     Py_INCREF(interp->import_func);
 
     /* Import the _imp module */
     impmod = PyInit__imp();
     if (impmod == NULL) {
-        return _Py_INIT_ERR("can't import _imp");
+        return _PyStatus_ERR("can't import _imp");
     }
     else if (verbose) {
         PySys_FormatStderr("import _imp # builtin\n");
     }
     if (_PyImport_SetModuleString("_imp", impmod) < 0) {
-        return _Py_INIT_ERR("can't save _imp to sys.modules");
+        return _PyStatus_ERR("can't save _imp to sys.modules");
     }
 
     /* Install importlib as the implementation of import */
     value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod);
     if (value == NULL) {
         PyErr_Print();
-        return _Py_INIT_ERR("importlib install failed");
+        return _PyStatus_ERR("importlib install failed");
     }
     Py_DECREF(value);
     Py_DECREF(impmod);
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
-static _PyInitError
+static PyStatus
 init_importlib_external(PyInterpreterState *interp)
 {
     PyObject *value;
@@ -204,7 +204,7 @@ init_importlib_external(PyInterpreterState *interp)
                                 "_install_external_importers", "");
     if (value == NULL) {
         PyErr_Print();
-        return _Py_INIT_ERR("external importer setup failed");
+        return _PyStatus_ERR("external importer setup failed");
     }
     Py_DECREF(value);
     return _PyImportZip_Init(interp);
@@ -265,7 +265,7 @@ static const char *_C_LOCALE_WARNING =
 static void
 emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime)
 {
-    const _PyPreConfig *preconfig = &runtime->preconfig;
+    const PyPreConfig *preconfig = &runtime->preconfig;
     if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected(1)) {
         PySys_FormatStderr("%s", _C_LOCALE_WARNING);
     }
@@ -437,7 +437,7 @@ _Py_SetLocaleFromEnv(int category)
 /* Global initializations.  Can be undone by Py_Finalize().  Don't
    call this twice without an intervening Py_Finalize() call.
 
-   Every call to _Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx
+   Every call to Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx
    must have a corresponding call to Py_Finalize.
 
    Locking: you must hold the interpreter lock while calling these APIs.
@@ -446,50 +446,50 @@ _Py_SetLocaleFromEnv(int category)
 
 */
 
-static _PyInitError
+static PyStatus
 pyinit_core_reconfigure(_PyRuntimeState *runtime,
                         PyInterpreterState **interp_p,
-                        const _PyCoreConfig *core_config)
+                        const PyConfig *config)
 {
-    _PyInitError err;
+    PyStatus status;
     PyThreadState *tstate = _PyThreadState_GET();
     if (!tstate) {
-        return _Py_INIT_ERR("failed to read thread state");
+        return _PyStatus_ERR("failed to read thread state");
     }
 
     PyInterpreterState *interp = tstate->interp;
     if (interp == NULL) {
-        return _Py_INIT_ERR("can't make main interpreter");
+        return _PyStatus_ERR("can't make main interpreter");
     }
     *interp_p = interp;
 
-    _PyCoreConfig_Write(core_config, runtime);
+    _PyConfig_Write(config, runtime);
 
-    err = _PyCoreConfig_Copy(&interp->core_config, core_config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyConfig_Copy(&interp->config, config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-    core_config = &interp->core_config;
+    config = &interp->config;
 
-    if (core_config->_install_importlib) {
-        err = _PyCoreConfig_SetPathConfig(core_config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+    if (config->_install_importlib) {
+        status = _PyConfig_SetPathConfig(config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
+static PyStatus
 pycore_init_runtime(_PyRuntimeState *runtime,
-                    const _PyCoreConfig *core_config)
+                    const PyConfig *config)
 {
     if (runtime->initialized) {
-        return _Py_INIT_ERR("main interpreter already initialized");
+        return _PyStatus_ERR("main interpreter already initialized");
     }
 
-    _PyCoreConfig_Write(core_config, runtime);
+    _PyConfig_Write(config, runtime);
 
     /* Py_Finalize leaves _Py_Finalizing set in order to help daemon
      * threads behave a little more gracefully at interpreter shutdown.
@@ -502,39 +502,39 @@ pycore_init_runtime(_PyRuntimeState *runtime,
      */
     runtime->finalizing = NULL;
 
-    _PyInitError err = _Py_HashRandomization_Init(core_config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _Py_HashRandomization_Init(config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = _PyInterpreterState_Enable(runtime);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyInterpreterState_Enable(runtime);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
+static PyStatus
 pycore_create_interpreter(_PyRuntimeState *runtime,
-                          const _PyCoreConfig *core_config,
+                          const PyConfig *config,
                           PyInterpreterState **interp_p)
 {
     PyInterpreterState *interp = PyInterpreterState_New();
     if (interp == NULL) {
-        return _Py_INIT_ERR("can't make main interpreter");
+        return _PyStatus_ERR("can't make main interpreter");
     }
     *interp_p = interp;
 
-    _PyInitError err = _PyCoreConfig_Copy(&interp->core_config, core_config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _PyConfig_Copy(&interp->config, config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-    core_config = &interp->core_config;
+    config = &interp->config;
 
     PyThreadState *tstate = PyThreadState_New(interp);
     if (tstate == NULL)
-        return _Py_INIT_ERR("can't make first thread");
+        return _PyStatus_ERR("can't make first thread");
     (void) PyThreadState_Swap(tstate);
 
     /* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because
@@ -550,249 +550,249 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
     /* Create the GIL */
     PyEval_InitThreads();
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
+static PyStatus
 pycore_init_types(void)
 {
-    _PyInitError err = _PyTypes_Init();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _PyTypes_Init();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = _PyUnicode_Init();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyUnicode_Init();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if (_PyStructSequence_Init() < 0) {
-        return _Py_INIT_ERR("can't initialize structseq");
+        return _PyStatus_ERR("can't initialize structseq");
     }
 
     if (!_PyLong_Init()) {
-        return _Py_INIT_ERR("can't init longs");
+        return _PyStatus_ERR("can't init longs");
     }
 
-    err = _PyExc_Init();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyExc_Init();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     if (!_PyFloat_Init()) {
-        return _Py_INIT_ERR("can't init float");
+        return _PyStatus_ERR("can't init float");
     }
 
     if (!_PyContext_Init()) {
-        return _Py_INIT_ERR("can't init context");
+        return _PyStatus_ERR("can't init context");
     }
 
-    err = _PyErr_Init();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyErr_Init();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
+static PyStatus
 pycore_init_builtins(PyInterpreterState *interp)
 {
     PyObject *bimod = _PyBuiltin_Init();
     if (bimod == NULL) {
-        return _Py_INIT_ERR("can't initialize builtins modules");
+        return _PyStatus_ERR("can't initialize builtins modules");
     }
     _PyImport_FixupBuiltin(bimod, "builtins", interp->modules);
 
     interp->builtins = PyModule_GetDict(bimod);
     if (interp->builtins == NULL) {
-        return _Py_INIT_ERR("can't initialize builtins dict");
+        return _PyStatus_ERR("can't initialize builtins dict");
     }
     Py_INCREF(interp->builtins);
 
-    _PyInitError err = _PyBuiltins_AddExceptions(bimod);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _PyBuiltins_AddExceptions(bimod);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
+static PyStatus
 pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod)
 {
-    _PyInitError err = _PyImport_Init(interp);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _PyImport_Init(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = _PyImportHooks_Init();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyImportHooks_Init();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     /* Initialize _warnings. */
     if (_PyWarnings_Init() == NULL) {
-        return _Py_INIT_ERR("can't initialize warnings");
+        return _PyStatus_ERR("can't initialize warnings");
     }
 
-    if (interp->core_config._install_importlib) {
-        err = _PyCoreConfig_SetPathConfig(&interp->core_config);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+    if (interp->config._install_importlib) {
+        status = _PyConfig_SetPathConfig(&interp->config);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
     /* This call sets up builtin and frozen import support */
-    if (interp->core_config._install_importlib) {
-        err = init_importlib(interp, sysmod);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+    if (interp->config._install_importlib) {
+        status = init_importlib(interp, sysmod);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-static _PyInitError
-pyinit_core_config(_PyRuntimeState *runtime,
-                   PyInterpreterState **interp_p,
-                   const _PyCoreConfig *core_config)
+static PyStatus
+pyinit_config(_PyRuntimeState *runtime,
+              PyInterpreterState **interp_p,
+              const PyConfig *config)
 {
     PyInterpreterState *interp;
 
-    _PyCoreConfig_Write(core_config, runtime);
+    _PyConfig_Write(config, runtime);
 
-    _PyInitError err = pycore_init_runtime(runtime, core_config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = pycore_init_runtime(runtime, config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = pycore_create_interpreter(runtime, core_config, &interp);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = pycore_create_interpreter(runtime, config, &interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-    core_config = &interp->core_config;
+    config = &interp->config;
     *interp_p = interp;
 
-    err = pycore_init_types();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = pycore_init_types();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     PyObject *sysmod;
-    err = _PySys_Create(runtime, interp, &sysmod);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PySys_Create(runtime, interp, &sysmod);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = pycore_init_builtins(interp);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = pycore_init_builtins(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = pycore_init_import_warnings(interp, sysmod);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = pycore_init_import_warnings(interp, sysmod);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     /* Only when we get here is the runtime core fully initialized */
     runtime->core_initialized = 1;
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-_PyInitError
-_Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args)
+PyStatus
+_Py_PreInitializeFromPyArgv(const PyPreConfig *src_config, const _PyArgv *args)
 {
-    _PyInitError err;
+    PyStatus status;
 
     if (src_config == NULL) {
-        return _Py_INIT_ERR("preinitialization config is NULL");
+        return _PyStatus_ERR("preinitialization config is NULL");
     }
 
-    err = _PyRuntime_Initialize();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyRuntime_Initialize();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
     _PyRuntimeState *runtime = &_PyRuntime;
 
     if (runtime->pre_initialized) {
         /* If it's already configured: ignored the new configuration */
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
-    _PyPreConfig config;
+    PyPreConfig config;
     _PyPreConfig_InitFromPreConfig(&config, src_config);
 
-    err = _PyPreConfig_Read(&config, args);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyPreConfig_Read(&config, args);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = _PyPreConfig_Write(&config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyPreConfig_Write(&config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     runtime->pre_initialized = 1;
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-_PyInitError
-_Py_PreInitializeFromArgs(const _PyPreConfig *src_config, Py_ssize_t argc, char **argv)
+PyStatus
+Py_PreInitializeFromBytesArgs(const PyPreConfig *src_config, Py_ssize_t argc, char **argv)
 {
     _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
     return _Py_PreInitializeFromPyArgv(src_config, &args);
 }
 
 
-_PyInitError
-_Py_PreInitializeFromWideArgs(const _PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv)
+PyStatus
+Py_PreInitializeFromArgs(const PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv)
 {
     _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
     return _Py_PreInitializeFromPyArgv(src_config, &args);
 }
 
 
-_PyInitError
-_Py_PreInitialize(const _PyPreConfig *src_config)
+PyStatus
+Py_PreInitialize(const PyPreConfig *src_config)
 {
     return _Py_PreInitializeFromPyArgv(src_config, NULL);
 }
 
 
-_PyInitError
-_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig,
-                                const _PyArgv *args)
+PyStatus
+_Py_PreInitializeFromConfig(const PyConfig *config,
+                            const _PyArgv *args)
 {
-    assert(coreconfig != NULL);
+    assert(config != NULL);
 
-    _PyInitError err = _PyRuntime_Initialize();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _PyRuntime_Initialize();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
     _PyRuntimeState *runtime = &_PyRuntime;
 
     if (runtime->pre_initialized) {
         /* Already initialized: do nothing */
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
-    _PyPreConfig preconfig;
-    _PyPreConfig_InitFromCoreConfig(&preconfig, coreconfig);
+    PyPreConfig preconfig;
+    _PyPreConfig_InitFromConfig(&preconfig, config);
 
-    if (!coreconfig->parse_argv) {
-        return _Py_PreInitialize(&preconfig);
+    if (!config->parse_argv) {
+        return Py_PreInitialize(&preconfig);
     }
     else if (args == NULL) {
         _PyArgv config_args = {
             .use_bytes_argv = 0,
-            .argc = coreconfig->argv.length,
-            .wchar_argv = coreconfig->argv.items};
+            .argc = config->argv.length,
+            .wchar_argv = config->argv.items};
         return _Py_PreInitializeFromPyArgv(&preconfig, &config_args);
     }
     else {
@@ -818,74 +818,66 @@ _Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig,
  * to the Python C API (unless the API is explicitly listed as being
  * safe to call without calling Py_Initialize first)
  */
-static _PyInitError
+static PyStatus
 pyinit_core(_PyRuntimeState *runtime,
-            const _PyCoreConfig *src_config,
-            const _PyArgv *args,
+            const PyConfig *src_config,
             PyInterpreterState **interp_p)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    err = _Py_PreInitializeFromCoreConfig(src_config, args);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _Py_PreInitializeFromConfig(src_config, NULL);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    _PyCoreConfig config;
-    _PyCoreConfig_InitCompatConfig(&config);
+    PyConfig config;
+    _PyConfig_InitCompatConfig(&config);
 
-    err = _PyCoreConfig_Copy(&config, src_config);
-    if (_Py_INIT_FAILED(err)) {
+    status = _PyConfig_Copy(&config, src_config);
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
-    if (args) {
-        err = _PyCoreConfig_SetPyArgv(&config, args);
-        if (_Py_INIT_FAILED(err)) {
-            goto done;
-        }
-    }
-
-    err = _PyCoreConfig_Read(&config);
-    if (_Py_INIT_FAILED(err)) {
+    status = PyConfig_Read(&config);
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
     if (!runtime->core_initialized) {
-        err = pyinit_core_config(runtime, interp_p, &config);
+        status = pyinit_config(runtime, interp_p, &config);
     }
     else {
-        err = pyinit_core_reconfigure(runtime, interp_p, &config);
+        status = pyinit_core_reconfigure(runtime, interp_p, &config);
     }
-    if (_Py_INIT_FAILED(err)) {
+    if (_PyStatus_EXCEPTION(status)) {
         goto done;
     }
 
 done:
-    _PyCoreConfig_Clear(&config);
-    return err;
+    PyConfig_Clear(&config);
+    return status;
 }
 
 
 /* Py_Initialize() has already been called: update the main interpreter
    configuration. Example of bpo-34008: Py_Main() called after
    Py_Initialize(). */
-static _PyInitError
+static PyStatus
 _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
 {
-    _PyCoreConfig *core_config = &interp->core_config;
+    PyConfig *config = &interp->config;
 
-    PyObject *argv = _PyWstrList_AsList(&core_config->argv);
+    PyObject *argv = _PyWideStringList_AsList(&config->argv);
     if (argv == NULL) {
-        return _Py_INIT_NO_MEMORY(); \
+        return _PyStatus_NO_MEMORY(); \
     }
 
     int res = PyDict_SetItemString(interp->sysdict, "argv", argv);
     Py_DECREF(argv);
     if (res < 0) {
-        return _Py_INIT_ERR("fail to set sys.argv");
+        return _PyStatus_ERR("fail to set sys.argv");
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 /* Update interpreter state based on supplied configuration settings
@@ -899,73 +891,73 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
  * Other errors should be reported as normal Python exceptions with a
  * non-zero return code.
  */
-static _PyInitError
+static PyStatus
 pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp)
 {
     if (!runtime->core_initialized) {
-        return _Py_INIT_ERR("runtime core not initialized");
+        return _PyStatus_ERR("runtime core not initialized");
     }
 
     /* Configure the main interpreter */
-    _PyCoreConfig *core_config = &interp->core_config;
+    PyConfig *config = &interp->config;
 
     if (runtime->initialized) {
         return _Py_ReconfigureMainInterpreter(interp);
     }
 
-    if (!core_config->_install_importlib) {
+    if (!config->_install_importlib) {
         /* Special mode for freeze_importlib: run with no import system
          *
          * This means anything which needs support from extension modules
          * or pure Python code in the standard library won't work.
          */
         runtime->initialized = 1;
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     if (_PyTime_Init() < 0) {
-        return _Py_INIT_ERR("can't initialize time");
+        return _PyStatus_ERR("can't initialize time");
     }
 
     if (_PySys_InitMain(runtime, interp) < 0) {
-        return _Py_INIT_ERR("can't finish initializing sys");
+        return _PyStatus_ERR("can't finish initializing sys");
     }
 
-    _PyInitError err = init_importlib_external(interp);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = init_importlib_external(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     /* initialize the faulthandler module */
-    err = _PyFaulthandler_Init(core_config->faulthandler);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyFaulthandler_Init(config->faulthandler);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = _PyUnicode_InitEncodings(interp);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyUnicode_InitEncodings(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    if (core_config->install_signal_handlers) {
-        err = init_signals();
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+    if (config->install_signal_handlers) {
+        status = init_signals();
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
-    if (_PyTraceMalloc_Init(core_config->tracemalloc) < 0) {
-        return _Py_INIT_ERR("can't initialize tracemalloc");
+    if (_PyTraceMalloc_Init(config->tracemalloc) < 0) {
+        return _PyStatus_ERR("can't initialize tracemalloc");
     }
 
-    err = add_main_module(interp);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = add_main_module(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = init_sys_streams(interp);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = init_sys_streams(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     /* Initialize warnings. */
@@ -982,10 +974,10 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp)
 
     runtime->initialized = 1;
 
-    if (core_config->site_import) {
-        err = init_import_size(); /* Module site */
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+    if (config->site_import) {
+        status = init_import_size(); /* Module site */
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
@@ -993,16 +985,16 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp)
     emit_stderr_warning_for_legacy_locale(runtime);
 #endif
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
-_PyInitError
+PyStatus
 _Py_InitializeMain(void)
 {
-    _PyInitError err = _PyRuntime_Initialize();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _PyRuntime_Initialize();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
     _PyRuntimeState *runtime = &_PyRuntime;
     PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
@@ -1011,74 +1003,47 @@ _Py_InitializeMain(void)
 }
 
 
-#undef _INIT_DEBUG_PRINT
-
-static _PyInitError
-pyinit_python(const _PyCoreConfig *config, const _PyArgv *args)
+PyStatus
+Py_InitializeFromConfig(const PyConfig *config)
 {
     if (config == NULL) {
-        return _Py_INIT_ERR("initialization config is NULL");
+        return _PyStatus_ERR("initialization config is NULL");
     }
 
-    _PyInitError err;
+    PyStatus status;
 
-    err = _PyRuntime_Initialize();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyRuntime_Initialize();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
     _PyRuntimeState *runtime = &_PyRuntime;
 
     PyInterpreterState *interp = NULL;
-    err = pyinit_core(runtime, config, args, &interp);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = pyinit_core(runtime, config, &interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-    config = &interp->core_config;
+    config = &interp->config;
 
     if (config->_init_main) {
-        err = pyinit_main(runtime, interp);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = pyinit_main(runtime, interp);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
     }
 
-    return _Py_INIT_OK();
-}
-
-
-_PyInitError
-_Py_InitializeFromArgs(const _PyCoreConfig *config,
-                       Py_ssize_t argc, char * const *argv)
-{
-    _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
-    return pyinit_python(config, &args);
-}
-
-
-_PyInitError
-_Py_InitializeFromWideArgs(const _PyCoreConfig *config,
-                           Py_ssize_t argc, wchar_t * const *argv)
-{
-    _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
-    return pyinit_python(config, &args);
-}
-
-
-_PyInitError
-_Py_InitializeFromConfig(const _PyCoreConfig *config)
-{
-    return pyinit_python(config, NULL);
+    return _PyStatus_OK();
 }
 
 
 void
 Py_InitializeEx(int install_sigs)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    err = _PyRuntime_Initialize();
-    if (_Py_INIT_FAILED(err)) {
-        _Py_ExitInitError(err);
+    status = _PyRuntime_Initialize();
+    if (_PyStatus_EXCEPTION(status)) {
+        Py_ExitStatusException(status);
     }
     _PyRuntimeState *runtime = &_PyRuntime;
 
@@ -1087,13 +1052,13 @@ Py_InitializeEx(int install_sigs)
         return;
     }
 
-    _PyCoreConfig config;
-    _PyCoreConfig_InitCompatConfig(&config);
+    PyConfig config;
+    _PyConfig_InitCompatConfig(&config);
     config.install_signal_handlers = install_sigs;
 
-    err = _Py_InitializeFromConfig(&config);
-    if (_Py_INIT_FAILED(err)) {
-        _Py_ExitInitError(err);
+    status = Py_InitializeFromConfig(&config);
+    if (_PyStatus_EXCEPTION(status)) {
+        Py_ExitStatusException(status);
     }
 }
 
@@ -1206,13 +1171,13 @@ Py_FinalizeEx(void)
     /* Copy the core config, PyInterpreterState_Delete() free
        the core config memory */
 #ifdef Py_REF_DEBUG
-    int show_ref_count = interp->core_config.show_ref_count;
+    int show_ref_count = interp->config.show_ref_count;
 #endif
 #ifdef Py_TRACE_REFS
-    int dump_refs = interp->core_config.dump_refs;
+    int dump_refs = interp->config.dump_refs;
 #endif
 #ifdef WITH_PYMALLOC
-    int malloc_stats = interp->core_config.malloc_stats;
+    int malloc_stats = interp->config.malloc_stats;
 #endif
 
     /* Remaining threads (e.g. daemon threads) will automatically exit
@@ -1412,19 +1377,19 @@ Py_Finalize(void)
 
 */
 
-static _PyInitError
+static PyStatus
 new_interpreter(PyThreadState **tstate_p)
 {
-    _PyInitError err;
+    PyStatus status;
 
-    err = _PyRuntime_Initialize();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyRuntime_Initialize();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
     _PyRuntimeState *runtime = &_PyRuntime;
 
     if (!runtime->initialized) {
-        return _Py_INIT_ERR("Py_Initialize must be called first");
+        return _PyStatus_ERR("Py_Initialize must be called first");
     }
 
     /* Issue #10915, #15751: The GIL API doesn't work with multiple
@@ -1434,49 +1399,49 @@ new_interpreter(PyThreadState **tstate_p)
     PyInterpreterState *interp = PyInterpreterState_New();
     if (interp == NULL) {
         *tstate_p = NULL;
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     PyThreadState *tstate = PyThreadState_New(interp);
     if (tstate == NULL) {
         PyInterpreterState_Delete(interp);
         *tstate_p = NULL;
-        return _Py_INIT_OK();
+        return _PyStatus_OK();
     }
 
     PyThreadState *save_tstate = PyThreadState_Swap(tstate);
 
     /* Copy the current interpreter config into the new interpreter */
-    _PyCoreConfig *core_config;
+    PyConfig *config;
     if (save_tstate != NULL) {
-        core_config = &save_tstate->interp->core_config;
+        config = &save_tstate->interp->config;
     } else {
         /* No current thread state, copy from the main interpreter */
         PyInterpreterState *main_interp = PyInterpreterState_Main();
-        core_config = &main_interp->core_config;
+        config = &main_interp->config;
     }
 
-    err = _PyCoreConfig_Copy(&interp->core_config, core_config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyConfig_Copy(&interp->config, config);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
-    core_config = &interp->core_config;
+    config = &interp->config;
 
-    err = _PyExc_Init();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyExc_Init();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = _PyErr_Init();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PyErr_Init();
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
 
     /* XXX The following is lax in error checking */
     PyObject *modules = PyDict_New();
     if (modules == NULL) {
-        return _Py_INIT_ERR("can't make modules dictionary");
+        return _PyStatus_ERR("can't make modules dictionary");
     }
     interp->modules = modules;
 
@@ -1489,7 +1454,7 @@ new_interpreter(PyThreadState **tstate_p)
         Py_INCREF(interp->sysdict);
         PyDict_SetItemString(interp->sysdict, "modules", modules);
         if (_PySys_InitMain(runtime, interp) < 0) {
-            return _Py_INIT_ERR("can't finish initializing sys");
+            return _PyStatus_ERR("can't finish initializing sys");
         }
     }
     else if (PyErr_Occurred()) {
@@ -1508,50 +1473,50 @@ new_interpreter(PyThreadState **tstate_p)
     }
 
     if (bimod != NULL && sysmod != NULL) {
-        err = _PyBuiltins_AddExceptions(bimod);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = _PyBuiltins_AddExceptions(bimod);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
-        err = _PySys_SetPreliminaryStderr(interp->sysdict);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = _PySys_SetPreliminaryStderr(interp->sysdict);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
-        err = _PyImportHooks_Init();
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = _PyImportHooks_Init();
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
-        err = init_importlib(interp, sysmod);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = init_importlib(interp, sysmod);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
-        err = init_importlib_external(interp);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = init_importlib_external(interp);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
-        err = _PyUnicode_InitEncodings(interp);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = _PyUnicode_InitEncodings(interp);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
-        err = init_sys_streams(interp);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = init_sys_streams(interp);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
-        err = add_main_module(interp);
-        if (_Py_INIT_FAILED(err)) {
-            return err;
+        status = add_main_module(interp);
+        if (_PyStatus_EXCEPTION(status)) {
+            return status;
         }
 
-        if (core_config->site_import) {
-            err = init_import_size();
-            if (_Py_INIT_FAILED(err)) {
-                return err;
+        if (config->site_import) {
+            status = init_import_size();
+            if (_PyStatus_EXCEPTION(status)) {
+                return status;
             }
         }
     }
@@ -1561,7 +1526,7 @@ new_interpreter(PyThreadState **tstate_p)
     }
 
     *tstate_p = tstate;
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 
 handle_error:
     /* Oops, it didn't work.  Undo it all. */
@@ -1573,16 +1538,16 @@ new_interpreter(PyThreadState **tstate_p)
     PyInterpreterState_Delete(interp);
 
     *tstate_p = NULL;
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 PyThreadState *
 Py_NewInterpreter(void)
 {
     PyThreadState *tstate = NULL;
-    _PyInitError err = new_interpreter(&tstate);
-    if (_Py_INIT_FAILED(err)) {
-        _Py_ExitInitError(err);
+    PyStatus status = new_interpreter(&tstate);
+    if (_PyStatus_EXCEPTION(status)) {
+        Py_ExitStatusException(status);
     }
     return tstate;
 
@@ -1627,29 +1592,29 @@ Py_EndInterpreter(PyThreadState *tstate)
 
 /* Add the __main__ module */
 
-static _PyInitError
+static PyStatus
 add_main_module(PyInterpreterState *interp)
 {
     PyObject *m, *d, *loader, *ann_dict;
     m = PyImport_AddModule("__main__");
     if (m == NULL)
-        return _Py_INIT_ERR("can't create __main__ module");
+        return _PyStatus_ERR("can't create __main__ module");
 
     d = PyModule_GetDict(m);
     ann_dict = PyDict_New();
     if ((ann_dict == NULL) ||
         (PyDict_SetItemString(d, "__annotations__", ann_dict) < 0)) {
-        return _Py_INIT_ERR("Failed to initialize __main__.__annotations__");
+        return _PyStatus_ERR("Failed to initialize __main__.__annotations__");
     }
     Py_DECREF(ann_dict);
 
     if (PyDict_GetItemString(d, "__builtins__") == NULL) {
         PyObject *bimod = PyImport_ImportModule("builtins");
         if (bimod == NULL) {
-            return _Py_INIT_ERR("Failed to retrieve builtins module");
+            return _PyStatus_ERR("Failed to retrieve builtins module");
         }
         if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) {
-            return _Py_INIT_ERR("Failed to initialize __main__.__builtins__");
+            return _PyStatus_ERR("Failed to initialize __main__.__builtins__");
         }
         Py_DECREF(bimod);
     }
@@ -1665,28 +1630,28 @@ add_main_module(PyInterpreterState *interp)
         PyObject *loader = PyObject_GetAttrString(interp->importlib,
                                                   "BuiltinImporter");
         if (loader == NULL) {
-            return _Py_INIT_ERR("Failed to retrieve BuiltinImporter");
+            return _PyStatus_ERR("Failed to retrieve BuiltinImporter");
         }
         if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
-            return _Py_INIT_ERR("Failed to initialize __main__.__loader__");
+            return _PyStatus_ERR("Failed to initialize __main__.__loader__");
         }
         Py_DECREF(loader);
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 /* Import the site module (not into __main__ though) */
 
-static _PyInitError
+static PyStatus
 init_import_size(void)
 {
     PyObject *m;
     m = PyImport_ImportModule("site");
     if (m == NULL) {
-        return _Py_INIT_ERR("Failed to import the site module");
+        return _PyStatus_ERR("Failed to import the site module");
     }
     Py_DECREF(m);
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 /* Check if a file descriptor is valid or not.
@@ -1727,7 +1692,7 @@ is_valid_fd(int fd)
 
 /* returns Py_None if the fd is not valid */
 static PyObject*
-create_stdio(const _PyCoreConfig *config, PyObject* io,
+create_stdio(const PyConfig *config, PyObject* io,
     int fd, int write_mode, const char* name,
     const wchar_t* encoding, const wchar_t* errors)
 {
@@ -1864,7 +1829,7 @@ create_stdio(const _PyCoreConfig *config, PyObject* io,
 }
 
 /* Initialize sys.stdin, stdout, stderr and builtins.open */
-static _PyInitError
+static PyStatus
 init_sys_streams(PyInterpreterState *interp)
 {
     PyObject *iomod = NULL, *wrapper;
@@ -1873,8 +1838,8 @@ init_sys_streams(PyInterpreterState *interp)
     PyObject *std = NULL;
     int fd;
     PyObject * encoding_attr;
-    _PyInitError res = _Py_INIT_OK();
-    _PyCoreConfig *config = &interp->core_config;
+    PyStatus res = _PyStatus_OK();
+    PyConfig *config = &interp->config;
 
     /* Check that stdin is not a directory
        Using shell redirection, you can redirect stdin to a directory,
@@ -1885,7 +1850,7 @@ init_sys_streams(PyInterpreterState *interp)
     struct _Py_stat_struct sb;
     if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 &&
         S_ISDIR(sb.st_mode)) {
-        return _Py_INIT_ERR("<stdin> is a directory, cannot continue");
+        return _PyStatus_ERR("<stdin> is a directory, cannot continue");
     }
 #endif
 
@@ -1981,7 +1946,7 @@ init_sys_streams(PyInterpreterState *interp)
     goto done;
 
 error:
-    res = _Py_INIT_ERR("can't initialize sys standard streams");
+    res = _PyStatus_ERR("can't initialize sys standard streams");
 
 done:
     _Py_ClearStandardStreamEncoding();
@@ -2183,16 +2148,16 @@ Py_FatalError(const char *msg)
 }
 
 void _Py_NO_RETURN
-_Py_ExitInitError(_PyInitError err)
+Py_ExitStatusException(PyStatus status)
 {
-    if (_Py_INIT_IS_EXIT(err)) {
-        exit(err.exitcode);
+    if (_PyStatus_IS_EXIT(status)) {
+        exit(status.exitcode);
     }
-    else if (_Py_INIT_IS_ERROR(err)) {
-        fatal_error(err._func, err.err_msg, 1);
+    else if (_PyStatus_IS_ERROR(status)) {
+        fatal_error(status.func, status.err_msg, 1);
     }
     else {
-        Py_FatalError("_Py_ExitInitError() must not be called on success");
+        Py_FatalError("Py_ExitStatusException() must not be called on success");
     }
 }
 
@@ -2284,7 +2249,7 @@ Py_Exit(int sts)
     exit(sts);
 }
 
-static _PyInitError
+static PyStatus
 init_signals(void)
 {
 #ifdef SIGPIPE
@@ -2298,9 +2263,9 @@ init_signals(void)
 #endif
     PyOS_InitInterrupts(); /* May imply initsignal() */
     if (PyErr_Occurred()) {
-        return _Py_INIT_ERR("can't import signal");
+        return _PyStatus_ERR("can't import signal");
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
diff --git a/Python/pystate.c b/Python/pystate.c
index 41c66223390d..d1a8d2472470 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -3,7 +3,7 @@
 
 #include "Python.h"
 #include "pycore_ceval.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_pymem.h"
 #include "pycore_pystate.h"
 #include "pycore_pylifecycle.h"
@@ -42,7 +42,7 @@ static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_st
 static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate);
 
 
-static _PyInitError
+static PyStatus
 _PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
 {
     /* We preserve the hook across init, because there is
@@ -60,7 +60,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
 
     _PyGC_Initialize(&runtime->gc);
     _PyEval_Initialize(&runtime->ceval);
-    _PyPreConfig_InitPythonConfig(&runtime->preconfig);
+    PyPreConfig_InitPythonConfig(&runtime->preconfig);
 
     runtime->gilstate.check_enabled = 1;
 
@@ -71,22 +71,22 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
 
     runtime->interpreters.mutex = PyThread_allocate_lock();
     if (runtime->interpreters.mutex == NULL) {
-        return _Py_INIT_ERR("Can't initialize threads for interpreter");
+        return _PyStatus_ERR("Can't initialize threads for interpreter");
     }
     runtime->interpreters.next_id = -1;
 
     runtime->xidregistry.mutex = PyThread_allocate_lock();
     if (runtime->xidregistry.mutex == NULL) {
-        return _Py_INIT_ERR("Can't initialize threads for cross-interpreter data registry");
+        return _PyStatus_ERR("Can't initialize threads for cross-interpreter data registry");
     }
 
     // Set it to the ID of the main thread of the main interpreter.
     runtime->main_thread = PyThread_get_thread_ident();
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
-_PyInitError
+PyStatus
 _PyRuntimeState_Init(_PyRuntimeState *runtime)
 {
     /* Force default allocator, since _PyRuntimeState_Fini() must
@@ -94,10 +94,10 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
     PyMemAllocatorEx old_alloc;
     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 
-    _PyInitError err = _PyRuntimeState_Init_impl(runtime);
+    PyStatus status = _PyRuntimeState_Init_impl(runtime);
 
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
-    return err;
+    return status;
 }
 
 void
@@ -163,7 +163,7 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
 static void _PyGILState_NoteThreadState(
     struct _gilstate_runtime_state *gilstate, PyThreadState* tstate);
 
-_PyInitError
+PyStatus
 _PyInterpreterState_Enable(_PyRuntimeState *runtime)
 {
     struct pyinterpreters *interpreters = &runtime->interpreters;
@@ -182,11 +182,11 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime)
         PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 
         if (interpreters->mutex == NULL) {
-            return _Py_INIT_ERR("Can't initialize threads for interpreter");
+            return _PyStatus_ERR("Can't initialize threads for interpreter");
         }
     }
 
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 PyInterpreterState *
@@ -205,8 +205,11 @@ PyInterpreterState_New(void)
     interp->id_refcount = -1;
     interp->check_interval = 100;
 
-    _PyInitError err = _PyCoreConfig_InitPythonConfig(&interp->core_config);
-    if (_Py_INIT_FAILED(err)) {
+    PyStatus status = PyConfig_InitPythonConfig(&interp->config);
+    if (_PyStatus_EXCEPTION(status)) {
+        /* Don't report status to caller: PyConfig_InitPythonConfig()
+           can only fail with a memory allocation error. */
+        PyConfig_Clear(&interp->config);
         PyMem_RawFree(interp);
         return NULL;
     }
@@ -269,7 +272,7 @@ _PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp)
 
     Py_CLEAR(interp->audit_hooks);
 
-    _PyCoreConfig_Clear(&interp->core_config);
+    PyConfig_Clear(&interp->config);
     Py_CLEAR(interp->codec_search_path);
     Py_CLEAR(interp->codec_search_cache);
     Py_CLEAR(interp->codec_error_registry);
@@ -523,12 +526,6 @@ _PyInterpreterState_RequireIDRef(PyInterpreterState *interp, int required)
     interp->requires_idref = required ? 1 : 0;
 }
 
-_PyCoreConfig *
-_PyInterpreterState_GetCoreConfig(PyInterpreterState *interp)
-{
-    return &interp->core_config;
-}
-
 PyObject *
 _PyInterpreterState_GetMainModule(PyInterpreterState *interp)
 {
@@ -775,7 +772,7 @@ _PyState_ClearModules(void)
 void
 PyThreadState_Clear(PyThreadState *tstate)
 {
-    int verbose = tstate->interp->core_config.verbose;
+    int verbose = tstate->interp->config.verbose;
 
     if (verbose && tstate->frame != NULL)
         fprintf(stderr,
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 26cb02aad5f1..665c9c9586e1 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -94,7 +94,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
     PyCompilerFlags local_flags;
     int nomem_count = 0;
 #ifdef Py_REF_DEBUG
-    int show_ref_count = _PyInterpreterState_Get()->core_config.show_ref_count;
+    int show_ref_count = _PyInterpreterState_Get()->config.show_ref_count;
 #endif
 
     filename = PyUnicode_DecodeFSDefault(filename_str);
@@ -584,7 +584,7 @@ print_error_text(PyObject *f, int offset, PyObject *text_obj)
 int
 _Py_HandleSystemExit(int *exitcode_p)
 {
-    int inspect = _PyInterpreterState_GET_UNSAFE()->core_config.inspect;
+    int inspect = _PyInterpreterState_GET_UNSAFE()->config.inspect;
     if (inspect) {
         /* Don't exit if -i flag was given. This flag is set to 0
          * when entering interactive mode for inspecting. */
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 08a1a2995e00..24018e25fa57 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -17,7 +17,7 @@ Data members:
 #include "Python.h"
 #include "code.h"
 #include "frameobject.h"
-#include "pycore_coreconfig.h"
+#include "pycore_initconfig.h"
 #include "pycore_pylifecycle.h"
 #include "pycore_pymem.h"
 #include "pycore_pathconfig.h"
@@ -752,7 +752,7 @@ sys_getfilesystemencoding_impl(PyObject *module)
 /*[clinic end generated code: output=1dc4bdbe9be44aa7 input=8475f8649b8c7d8c]*/
 {
     PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
-    const _PyCoreConfig *config = &interp->core_config;
+    const PyConfig *config = &interp->config;
     return PyUnicode_FromWideChar(config->filesystem_encoding, -1);
 }
 
@@ -767,7 +767,7 @@ sys_getfilesystemencodeerrors_impl(PyObject *module)
 /*[clinic end generated code: output=ba77b36bbf7c96f5 input=22a1e8365566f1e5]*/
 {
     PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
-    const _PyCoreConfig *config = &interp->core_config;
+    const PyConfig *config = &interp->config;
     return PyUnicode_FromWideChar(config->filesystem_errors, -1);
 }
 
@@ -2475,8 +2475,8 @@ make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp)
 {
     int pos = 0;
     PyObject *seq;
-    const _PyPreConfig *preconfig = &runtime->preconfig;
-    const _PyCoreConfig *config = &interp->core_config;
+    const PyPreConfig *preconfig = &runtime->preconfig;
+    const PyConfig *config = &interp->config;
 
     seq = PyStructSequence_New(&FlagsType);
     if (seq == NULL)
@@ -2690,7 +2690,7 @@ static struct PyModuleDef sysmodule = {
         }                                                  \
     } while (0)
 
-static _PyInitError
+static PyStatus
 _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp,
                 PyObject *sysdict)
 {
@@ -2827,13 +2827,13 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp,
     if (PyErr_Occurred()) {
         goto err_occurred;
     }
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 
 type_init_failed:
-    return _Py_INIT_ERR("failed to initialize a type");
+    return _PyStatus_ERR("failed to initialize a type");
 
 err_occurred:
-    return _Py_INIT_ERR("can't initialize sys module");
+    return _PyStatus_ERR("can't initialize sys module");
 }
 
 #undef SET_SYS_FROM_STRING
@@ -2885,7 +2885,7 @@ sys_add_xoption(PyObject *opts, const wchar_t *s)
 
 
 static PyObject*
-sys_create_xoptions_dict(const _PyCoreConfig *config)
+sys_create_xoptions_dict(const PyConfig *config)
 {
     Py_ssize_t nxoption = config->xoptions.length;
     wchar_t * const * xoptions = config->xoptions.items;
@@ -2910,12 +2910,12 @@ int
 _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp)
 {
     PyObject *sysdict = interp->sysdict;
-    const _PyCoreConfig *config = &interp->core_config;
+    const PyConfig *config = &interp->config;
     int res;
 
 #define COPY_LIST(KEY, VALUE) \
     do { \
-        PyObject *list = _PyWstrList_AsList(&(VALUE)); \
+        PyObject *list = _PyWideStringList_AsList(&(VALUE)); \
         if (list == NULL) { \
             return -1; \
         } \
@@ -3003,7 +3003,7 @@ _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp)
    infrastructure for the io module in place.
 
    Use UTF-8/surrogateescape and ignore EAGAIN errors. */
-_PyInitError
+PyStatus
 _PySys_SetPreliminaryStderr(PyObject *sysdict)
 {
     PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
@@ -3017,56 +3017,56 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict)
         goto error;
     }
     Py_DECREF(pstderr);
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 
 error:
     Py_XDECREF(pstderr);
-    return _Py_INIT_ERR("can't set preliminary stderr");
+    return _PyStatus_ERR("can't set preliminary stderr");
 }
 
 
 /* Create sys module without all attributes: _PySys_InitMain() should be called
    later to add remaining attributes. */
-_PyInitError
+PyStatus
 _PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp,
               PyObject **sysmod_p)
 {
     PyObject *modules = PyDict_New();
     if (modules == NULL) {
-        return _Py_INIT_ERR("can't make modules dictionary");
+        return _PyStatus_ERR("can't make modules dictionary");
     }
     interp->modules = modules;
 
     PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
     if (sysmod == NULL) {
-        return _Py_INIT_ERR("failed to create a module object");
+        return _PyStatus_ERR("failed to create a module object");
     }
 
     PyObject *sysdict = PyModule_GetDict(sysmod);
     if (sysdict == NULL) {
-        return _Py_INIT_ERR("can't initialize sys dict");
+        return _PyStatus_ERR("can't initialize sys dict");
     }
     Py_INCREF(sysdict);
     interp->sysdict = sysdict;
 
     if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) {
-        return _Py_INIT_ERR("can't initialize sys module");
+        return _PyStatus_ERR("can't initialize sys module");
     }
 
-    _PyInitError err = _PySys_SetPreliminaryStderr(sysdict);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
-    err = _PySys_InitCore(runtime, interp, sysdict);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
+    status = _PySys_InitCore(runtime, interp, sysdict);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
     }
 
     _PyImport_FixupBuiltin(sysmod, "sys", interp->modules);
 
     *sysmod_p = sysmod;
-    return _Py_INIT_OK();
+    return _PyStatus_OK();
 }
 
 
@@ -3156,7 +3156,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
     if (updatepath) {
         /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path.
            If argv[0] is a symlink, use the real path. */
-        const _PyWstrList argv_list = {.length = argc, .items = argv};
+        const PyWideStringList argv_list = {.length = argc, .items = argv};
         PyObject *path0 = NULL;
         if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) {
             if (path0 == NULL) {



More information about the Python-checkins mailing list