summaryrefslogtreecommitdiffstats
path: root/Doc/c-api/init_config.rst
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-05-27 14:39:22 (GMT)
committerGitHub <noreply@github.com>2019-05-27 14:39:22 (GMT)
commit331a6a56e9a9c72f3e4605987fabdaec72677702 (patch)
tree49d20cedd9df4371f2410b2fb24255535ca02c50 /Doc/c-api/init_config.rst
parent8cd5165ba05ff57cfdbbc71c393bddad1ce1ab87 (diff)
downloadcpython-331a6a56e9a9c72f3e4605987fabdaec72677702.zip
cpython-331a6a56e9a9c72f3e4605987fabdaec72677702.tar.gz
cpython-331a6a56e9a9c72f3e4605987fabdaec72677702.tar.bz2
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()
Diffstat (limited to 'Doc/c-api/init_config.rst')
-rw-r--r--Doc/c-api/init_config.rst1018
1 files changed, 1018 insertions, 0 deletions
diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst
new file mode 100644
index 0000000..0d94e6b
--- /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);
+ }
+ }