2024-01-19 11:43:45 -05:00
|
|
|
PEP: 741
|
|
|
|
Title: Python Configuration C API
|
|
|
|
Author: Victor Stinner <vstinner@python.org>
|
2024-03-14 11:18:19 -04:00
|
|
|
Discussions-To: https://discuss.python.org/t/pep-741-python-configuration-c-api-second-version/45403
|
2024-01-19 11:43:45 -05:00
|
|
|
Status: Draft
|
|
|
|
Type: Standards Track
|
|
|
|
Created: 18-Jan-2024
|
2024-05-25 09:06:53 -04:00
|
|
|
Python-Version: 3.14
|
2024-02-08 19:00:51 -05:00
|
|
|
Post-History: `19-Jan-2024 <https://discuss.python.org/t/pep-741-python-configuration-c-api/43637>`__,
|
|
|
|
`08-Feb-2024 <https://discuss.python.org/t/pep-741-python-configuration-c-api-second-version/45403>`__,
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
Abstract
|
|
|
|
========
|
|
|
|
|
2024-05-25 09:06:53 -04:00
|
|
|
Add a C API to configure the Python initialization without relying on C
|
|
|
|
structures and the ability to make ABI-compatible changes in the future.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
Complete :pep:`587` API by adding ``PyInitConfig_AddModule()`` which can be
|
2024-02-08 13:40:50 -05:00
|
|
|
used to add a built-in extension module; feature previously referred to
|
|
|
|
as the "inittab".
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-03-09 18:54:18 -05:00
|
|
|
Add ``PyConfig_Get()`` and ``PyConfig_Set()`` functions to
|
2024-05-29 08:15:22 -04:00
|
|
|
get and set the current runtime configuration.
|
2024-03-09 18:54:18 -05:00
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
:pep:`587` "Python Initialization Configuration" unified all the ways to
|
2024-05-25 09:06:53 -04:00
|
|
|
configure the Python **initialization**. This PEP unifies also the
|
|
|
|
configuration of the Python **preinitialization** and the Python
|
2024-05-29 08:15:22 -04:00
|
|
|
**initialization** in a single API. Moreover, this PEP only provides a
|
|
|
|
single choice to embed Python, instead of having two "Python" and
|
|
|
|
"Isolated" choices (:pep:`587`), to simplify the API further.
|
2024-02-08 13:40:50 -05:00
|
|
|
|
|
|
|
This new API replaces the deprecated and incomplete legacy API which is
|
|
|
|
scheduled for removal between Python 3.13 and Python 3.15.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-05-29 08:15:22 -04:00
|
|
|
The lower level :pep:`587` ``PyConfig`` API remains available for use
|
|
|
|
cases with an intentionally higher level of coupling to CPython
|
|
|
|
implementation details (such as emulating the full functionality of
|
|
|
|
CPython's CLI, including its configuration mechanisms).
|
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
Rationale
|
|
|
|
=========
|
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
Get the runtime configuration
|
2024-01-19 11:43:45 -05:00
|
|
|
-----------------------------
|
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
:pep:`587` has no API to **get** the **current** runtime configuration,
|
|
|
|
only to **configure** the Python **initialization**.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
For example, the global configuration variable
|
|
|
|
``Py_UnbufferedStdioFlag`` was deprecated in Python 3.12 and using
|
|
|
|
``PyConfig.buffered_stdio`` is recommended instead. It only works to
|
|
|
|
configure Python, there is no public API to get
|
|
|
|
``PyConfig.buffered_stdio``.
|
|
|
|
|
|
|
|
Users of the limited C API are asking for a public API to get the
|
2024-03-09 19:23:55 -05:00
|
|
|
current runtime configuration.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-03-14 08:47:23 -04:00
|
|
|
Cython needs to get the ``optimization_level`` configuration option:
|
2024-03-08 09:35:01 -05:00
|
|
|
`issue <https://github.com/python/cpython/issues/99872>`_.
|
|
|
|
|
|
|
|
When global configuration variables were deprecated in 2022, `Marc-André
|
|
|
|
Lemburg requested
|
2024-03-09 15:44:22 -05:00
|
|
|
<https://github.com/python/cpython/issues/93103#issuecomment-1136462708>`__
|
2024-03-09 18:54:18 -05:00
|
|
|
a C API to access these configuration variables at runtime (not only
|
2024-03-08 09:35:01 -05:00
|
|
|
during Python initialization).
|
|
|
|
|
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
Security fix
|
|
|
|
------------
|
|
|
|
|
|
|
|
To fix `CVE-2020-10735
|
|
|
|
<https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735>`_,
|
|
|
|
a denial-of-service when converting very a large string to an integer (in base
|
|
|
|
10), it was discussed to add a new ``PyConfig`` member to stable
|
|
|
|
branches which affects the ABI.
|
|
|
|
|
|
|
|
Gregory P. Smith proposed a different API using text based configuration
|
|
|
|
file to not be limited by ``PyConfig`` members: `FR: Allow private
|
|
|
|
runtime config to enable extending without breaking the PyConfig ABI
|
|
|
|
<https://discuss.python.org/t/fr-allow-private-runtime-config-to-enable-extending-without-breaking-the-pyconfig-abi/18004>`__
|
|
|
|
(August 2022).
|
|
|
|
|
|
|
|
In the end, it was decided to not add a new ``PyConfig`` member to
|
|
|
|
stable branches, but only add a new ``PyConfig.int_max_str_digits``
|
|
|
|
member to the development branch (which became Python 3.12). A dedicated
|
|
|
|
private global variable (unrelated to ``PyConfig``) is used in stable
|
|
|
|
branches.
|
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
Redundancy between PyPreConfig and PyConfig
|
|
|
|
-------------------------------------------
|
|
|
|
|
|
|
|
The Python preinitialization uses the ``PyPreConfig`` structure and the
|
|
|
|
Python initialization uses the ``PyConfig`` structure. Both structures
|
|
|
|
have four duplicated members: ``dev_mode``, ``parse_argv``, ``isolated``
|
|
|
|
and ``use_environment``.
|
|
|
|
|
|
|
|
The redundancy is caused by the fact that the two structures are
|
|
|
|
separated, whereas some ``PyConfig`` members are needed by the
|
|
|
|
preinitialization.
|
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
|
|
|
|
Embedding Python
|
|
|
|
----------------
|
|
|
|
|
2024-02-08 13:40:50 -05:00
|
|
|
Applications embedding Python
|
2024-03-08 09:35:01 -05:00
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2024-02-08 13:40:50 -05:00
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
* `Blender 3D graphics <https://www.blender.org/>`_.
|
|
|
|
* `fontforge <https://fontforge.org/>`_ font editor.
|
|
|
|
* `Gimp <https://www.gimp.org/>`_.
|
|
|
|
* `LibreOffice <https://www.libreoffice.org/>`_.
|
|
|
|
* `OBS Studio <https://obsproject.com/>`_.
|
|
|
|
* `Tiled <https://www.mapeditor.org/>`_.
|
|
|
|
* `vim <https://www.vim.org/>`_ text editor.
|
|
|
|
|
|
|
|
On Linux, FreeBSD and macOS, applications are usually either statically
|
|
|
|
linked to a ``libpython``, or load dynamically a ``libpython`` . The
|
2024-03-08 09:35:01 -05:00
|
|
|
``libpython`` shared library is versioned, example:
|
|
|
|
``libpython3.12.so`` for Python 3.12 on Linux.
|
2024-02-08 13:40:50 -05:00
|
|
|
|
|
|
|
The vim project can target the stable ABI. Usually, the "system Python"
|
|
|
|
version is used. It's not currently possible to select which Python
|
|
|
|
version to use. Users would like the ability to select a newer Python
|
|
|
|
on demand.
|
|
|
|
|
|
|
|
On Linux, another approach to deploy an application embedding Python,
|
|
|
|
such as GIMP, is to include Python in Flatpack, AppImage or Snap
|
|
|
|
"container". In this case, the application brings its own copy of Python
|
|
|
|
version with the container.
|
|
|
|
|
|
|
|
Libraries embedding Python
|
2024-03-08 09:35:01 -05:00
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2024-02-08 13:40:50 -05:00
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
* `Apache mod_wsgi <https://modwsgi.readthedocs.io/>`_
|
|
|
|
(`source <https://github.com/GrahamDumpleton/mod_wsgi/blob/f54eadd6da8e3da0faccd497d4165de435b97242/src/server/wsgi_interp.c#L2367-L2404>`__).
|
|
|
|
* `nimpy <https://github.com/yglukhov/nimpy>`_:
|
|
|
|
Nim - Python bridge.
|
|
|
|
* `PyO3 <https://github.com/PyO3/pyo3>`__:
|
|
|
|
Rust bindings for the Python interpreter.
|
|
|
|
|
|
|
|
Utilities creating standalone applications
|
2024-03-08 09:35:01 -05:00
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2024-02-08 13:40:50 -05:00
|
|
|
|
|
|
|
* `py2app <https://py2app.readthedocs.io/>`_ for macOS.
|
|
|
|
* `py2exe <http://www.py2exe.org/>`_ for Windows.
|
|
|
|
* `pyinstaller <https://pyinstaller.org/>`_.
|
|
|
|
* `PyOxidizer <https://github.com/indygreg/PyOxidizer>`_:
|
|
|
|
it uses the PEP 587 PyConfig API.
|
|
|
|
|
|
|
|
These utilities create standalone applications, they are not linked to
|
|
|
|
libpython.
|
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
Set the runtime configuration
|
2024-03-09 15:44:22 -05:00
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
`Marc-André Lemburg requested
|
|
|
|
<https://discuss.python.org/t/fr-allow-private-runtime-config-to-enable-extending-without-breaking-the-pyconfig-abi/18004/34>`__
|
2024-03-09 18:54:18 -05:00
|
|
|
a C API to **set** the value of some configuration options at runtime:
|
2024-03-09 15:44:22 -05:00
|
|
|
|
|
|
|
* ``optimization_level``
|
|
|
|
* ``verbose``
|
|
|
|
* ``parser_debug``
|
|
|
|
* ``inspect``
|
|
|
|
* ``write_bytecode``
|
|
|
|
|
2024-03-14 08:47:23 -04:00
|
|
|
Previously, it was possible to set directly global configuration
|
|
|
|
variables:
|
|
|
|
|
|
|
|
* ``Py_OptimizeFlag``
|
|
|
|
* ``Py_VerboseFlag``
|
|
|
|
* ``Py_DebugFlag``
|
|
|
|
* ``Py_InspectFlag``
|
|
|
|
* ``Py_DontWriteBytecodeFlag``
|
|
|
|
|
|
|
|
But these configuration flags were deprecated in Python 3.12 and are
|
|
|
|
scheduled for removal in Python 3.14.
|
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
Specification
|
|
|
|
=============
|
|
|
|
|
2024-02-08 13:40:50 -05:00
|
|
|
Add C API functions and structure to configure the Python
|
|
|
|
initialization:
|
|
|
|
|
2024-03-09 18:54:18 -05:00
|
|
|
* Create config:
|
|
|
|
|
|
|
|
* ``PyInitConfig`` opaque structure.
|
2024-05-29 08:15:22 -04:00
|
|
|
* ``PyInitConfig_Create()``.
|
2024-03-09 18:54:18 -05:00
|
|
|
* ``PyInitConfig_Free(config)``.
|
|
|
|
|
|
|
|
* Get options:
|
|
|
|
|
|
|
|
* ``PyInitConfig_HasOption(config, name)``.
|
|
|
|
* ``PyInitConfig_GetInt(config, name, &value)``.
|
|
|
|
* ``PyInitConfig_GetStr(config, name, &value)``.
|
|
|
|
* ``PyInitConfig_GetStrList(config, name, &length, &items)``.
|
|
|
|
* ``PyInitConfig_FreeStrList()``.
|
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
* Set options:
|
2024-03-09 18:54:18 -05:00
|
|
|
|
|
|
|
* ``PyInitConfig_SetInt(config, name, value)``.
|
|
|
|
* ``PyInitConfig_SetStr(config, name, value)``.
|
|
|
|
* ``PyInitConfig_SetStrList(config, name, length, items)``.
|
|
|
|
* ``PyInitConfig_AddModule(config, name, initfunc)``
|
|
|
|
|
|
|
|
* Initialize:
|
|
|
|
|
|
|
|
* ``Py_InitializeFromInitConfig(config)``.
|
|
|
|
|
|
|
|
* Error handling:
|
|
|
|
|
|
|
|
* ``PyInitConfig_GetError(config, &err_msg)``.
|
2024-03-14 08:47:23 -04:00
|
|
|
* ``PyInitConfig_GetExitcode(config, &exitcode)``.
|
2024-03-09 18:54:18 -05:00
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
Add C API functions to get and set the current runtime configuration:
|
2024-03-09 18:54:18 -05:00
|
|
|
|
2024-05-25 09:06:53 -04:00
|
|
|
* ``PyConfig_Get(name)``.
|
2024-02-08 13:40:50 -05:00
|
|
|
* ``PyConfig_GetInt(name, &value)``.
|
2024-03-09 15:44:22 -05:00
|
|
|
* ``PyConfig_Set(name)``.
|
2024-05-25 09:06:53 -04:00
|
|
|
* ``PyConfig_Names()``.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
The C API uses null-terminated UTF-8 encoded strings to refer to a
|
2024-05-25 09:06:53 -04:00
|
|
|
configuration option name.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-05-25 09:06:53 -04:00
|
|
|
These C API functions are excluded from the limited C API.
|
|
|
|
|
|
|
|
PyInitConfig structure
|
|
|
|
----------------------
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-03-10 03:35:56 -04:00
|
|
|
The ``PyInitConfig`` structure is implemented by combining the four
|
2024-02-08 13:40:50 -05:00
|
|
|
structures of the ``PyConfig`` API and has an ``inittab`` member as
|
|
|
|
well:
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
* ``PyPreConfig preconfig``
|
|
|
|
* ``PyConfig config``
|
|
|
|
* ``PyStatus status``
|
2024-02-08 13:40:50 -05:00
|
|
|
* ``struct _inittab *inittab`` for ``PyInitConfig_AddModule()``
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
The ``PyStatus`` status is no longer separated, but part of the unified
|
|
|
|
``PyInitConfig`` structure, which makes the API easier to use.
|
|
|
|
|
|
|
|
|
|
|
|
Configuration Options
|
|
|
|
---------------------
|
|
|
|
|
2024-02-08 13:40:50 -05:00
|
|
|
Configuration options are named after ``PyPreConfig`` and ``PyConfig``
|
2024-03-09 15:44:22 -05:00
|
|
|
structure members. See the `PyPreConfig documentation
|
2024-02-08 13:40:50 -05:00
|
|
|
<https://docs.python.org/dev/c-api/init_config.html#pypreconfig>`_ and
|
|
|
|
the `PyConfig documentation
|
|
|
|
<https://docs.python.org/dev/c-api/init_config.html#pyconfig>`_.
|
|
|
|
|
|
|
|
Deprecating and removing configuration options is out of the scope of
|
|
|
|
the PEP and should be discussed on a case by case basis.
|
|
|
|
|
2024-03-09 15:44:22 -05:00
|
|
|
Public configuration options
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
2024-03-09 18:54:18 -05:00
|
|
|
Following options can be get by ``PyConfig_Get()`` and set and
|
|
|
|
``PyConfig_Set()``.
|
2024-03-09 15:44:22 -05:00
|
|
|
|
|
|
|
.. list-table::
|
2024-03-09 16:12:42 -05:00
|
|
|
:widths: 20 20 50
|
|
|
|
:header-rows: 1
|
2024-03-09 15:44:22 -05:00
|
|
|
|
|
|
|
* - Option
|
|
|
|
- Type
|
|
|
|
- Comment
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``argv``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``list[str]``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.argv``.
|
|
|
|
* - ``base_exec_prefix``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.base_exec_prefix``.
|
|
|
|
* - ``base_executable``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.base_executable``.
|
|
|
|
* - ``base_prefix``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.base_prefix``.
|
|
|
|
* - ``bytes_warning``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``int``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.flags.bytes_warning``.
|
|
|
|
* - ``exec_prefix``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.base_prefix``.
|
|
|
|
* - ``executable``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.executable``.
|
|
|
|
* - ``inspect``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
- API: ``sys.flags.inspect`` (``int``).
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``int_max_str_digits``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``int``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.flags.int_max_str_digits``,
|
2024-03-09 15:44:22 -05:00
|
|
|
``sys.get_int_max_str_digits()`` and
|
|
|
|
``sys.set_int_max_str_digits()``.
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``interactive``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.flags.interactive``.
|
|
|
|
* - ``module_search_paths``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``list[str]``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.path``.
|
|
|
|
* - ``optimization_level``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``int``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.flags.optimize``.
|
|
|
|
* - ``parser_debug``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
- API: ``sys.flags.debug`` (``int``).
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``platlibdir``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.platlibdir``.
|
|
|
|
* - ``prefix``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.base_prefix``.
|
|
|
|
* - ``pycache_prefix``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.pycache_prefix``.
|
|
|
|
* - ``quiet``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
- API: ``sys.flags.quiet`` (``int``).
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``stdlib_dir``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys._stdlib_dir``.
|
|
|
|
* - ``use_environment``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
- API: ``sys.flags.ignore_environment`` (``int``).
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``verbose``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``int``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.flags.verbose``.
|
|
|
|
* - ``warnoptions``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``list[str]``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.warnoptions``.
|
|
|
|
* - ``write_bytecode``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
- API: ``sys.flags.dont_write_bytecode`` (``int``) and ``sys.dont_write_bytecode`` (``bool``).
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``xoptions``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``dict[str, str]``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys._xoptions``.
|
2024-03-09 15:44:22 -05:00
|
|
|
|
|
|
|
Some option names are different than ``sys`` attributes, such as
|
2024-03-09 18:54:18 -05:00
|
|
|
``optimization_level`` option and ``sys.flags.optimize`` attribute.
|
|
|
|
``PyConfig_Set()`` sets the corresponding ``sys`` attribute.
|
2024-03-09 15:44:22 -05:00
|
|
|
|
2024-03-10 03:35:56 -04:00
|
|
|
The ``xoptions`` is a list of strings in ``PyInitConfig`` where each
|
|
|
|
string has the format ``key`` (*value* is ``True`` implicitly) or
|
|
|
|
``key=value``. In the current runtime configuration, it becomes a
|
|
|
|
dictionary (``key: str`` → ``value: str | True``).
|
|
|
|
|
2024-03-09 15:44:22 -05:00
|
|
|
Read-only configuration options
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
2024-03-09 18:54:18 -05:00
|
|
|
Following options can be get ``PyConfig_Get()``, but cannot be set by
|
|
|
|
``PyConfig_Set()``.
|
2024-03-09 15:44:22 -05:00
|
|
|
|
|
|
|
.. list-table::
|
2024-03-09 16:12:42 -05:00
|
|
|
:widths: 20 20 50
|
|
|
|
:header-rows: 1
|
2024-03-09 15:44:22 -05:00
|
|
|
|
|
|
|
* - Option
|
|
|
|
- Type
|
|
|
|
- Comment
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``allocator``
|
|
|
|
- ``int``
|
2024-03-09 15:44:22 -05:00
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``buffered_stdio``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``check_hash_pycs_mode``
|
|
|
|
- ``str``
|
|
|
|
- API: ``imp.check_hash_pycs_mode``.
|
|
|
|
* - ``code_debug_ranges``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``coerce_c_locale``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``coerce_c_locale_warn``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``configure_c_stdio``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``configure_locale``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``cpu_count``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``int``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``os.cpu_count()`` (``int | None``).
|
|
|
|
* - ``dev_mode``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``sys.flags.dev_mode``.
|
|
|
|
* - ``dump_refs``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``dump_refs_file``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``faulthandler``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
2024-03-09 18:54:18 -05:00
|
|
|
- API: ``faulthandler.is_enabled()``.
|
|
|
|
* - ``filesystem_encoding``
|
|
|
|
- ``str``
|
|
|
|
- API: ``sys.getfilesystemencoding()``.
|
|
|
|
* - ``filesystem_errors``
|
|
|
|
- ``str``
|
|
|
|
- API: ``sys.getfilesystemencodeerrors()``.
|
|
|
|
* - ``hash_seed``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``int``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``home``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``import_time``
|
|
|
|
- ``bool``
|
|
|
|
-
|
|
|
|
* - ``install_signal_handlers``
|
|
|
|
- ``bool``
|
|
|
|
-
|
|
|
|
* - ``isolated``
|
|
|
|
- ``bool``
|
|
|
|
- API: ``sys.flags.isolated`` (``int``).
|
|
|
|
* - ``legacy_windows_fs_encoding``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``legacy_windows_stdio``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
- Windows only
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``malloc_stats``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``module_search_paths_set``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``orig_argv``
|
|
|
|
- ``list[str]``
|
|
|
|
- API: ``sys.orig_argv``.
|
|
|
|
* - ``pathconfig_warnings``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``parse_argv``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``perf_profiling``
|
|
|
|
- ``bool``
|
|
|
|
- API: ``sys.is_stack_trampoline_active()``.
|
|
|
|
* - ``program_name``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``pythonpath_env``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``run_command``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``run_filename``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``run_module``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``run_presite``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
- need a debug build.
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``safe_path``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``show_ref_count``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``site_import``
|
|
|
|
- ``bool``
|
|
|
|
- API: ``sys.flags.no_site`` (``int``).
|
|
|
|
* - ``skip_source_first_line``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``stdio_encoding``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
- API: ``sys.stdin.encoding``, ``sys.stdout.encoding`` and
|
2024-03-09 18:54:18 -05:00
|
|
|
``sys.stderr.encoding``.
|
|
|
|
* - ``stdio_errors``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
- API: ``sys.stdin.errors``, ``sys.stdout.errors`` and
|
2024-03-09 18:54:18 -05:00
|
|
|
``sys.stderr.errors``.
|
|
|
|
* - ``sys_path_0``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``str``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``tracemalloc``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``int``
|
|
|
|
- API: ``tracemalloc.is_tracing()`` (``bool``).
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``use_frozen_modules``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``use_hash_seed``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``utf8_mode``
|
|
|
|
- ``bool``
|
|
|
|
-
|
|
|
|
* - ``user_site_directory``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
- API: ``sys.flags.no_user_site`` (``int``).
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``warn_default_encoding``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``_install_importlib``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``_init_main``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``_is_python_build``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
-
|
2024-03-09 18:54:18 -05:00
|
|
|
* - ``_pystats``
|
2024-03-09 15:44:22 -05:00
|
|
|
- ``bool``
|
|
|
|
- API: ``sys._stats_on()``, ``sys._stats_off()``.
|
|
|
|
Need a ``Py_STATS`` build.
|
|
|
|
|
2024-02-08 13:40:50 -05:00
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
Create Config
|
|
|
|
-------------
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
``PyInitConfig`` structure:
|
|
|
|
Opaque structure to configure the Python preinitialization and the
|
|
|
|
Python initialization.
|
|
|
|
|
2024-05-29 08:15:22 -04:00
|
|
|
``PyInitConfig* PyInitConfig_Create(void)``:
|
2024-01-19 11:43:45 -05:00
|
|
|
Create a new initialization configuration using default values
|
2024-05-29 08:15:22 -04:00
|
|
|
of the `Isolated Configuration
|
|
|
|
<https://docs.python.org/dev/c-api/init_config.html#isolated-configuration>`_.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
It must be freed with ``PyInitConfig_Free()``.
|
|
|
|
|
|
|
|
Return ``NULL`` on memory allocation failure.
|
|
|
|
|
|
|
|
``void PyInitConfig_Free(PyInitConfig *config)``:
|
|
|
|
Free memory of an initialization configuration.
|
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
Get Options
|
|
|
|
-----------
|
2024-02-08 13:40:50 -05:00
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
The configuration option *name* parameter must be a non-NULL
|
|
|
|
null-terminated UTF-8 encoded string.
|
|
|
|
|
|
|
|
``int PyInitConfig_HasOption(PyInitConfig *config, const char *name)``:
|
|
|
|
Test if the configuration has an option called *name*.
|
|
|
|
|
|
|
|
Return ``1`` if the option exists, or return ``0`` otherwise.
|
|
|
|
|
2024-02-08 13:40:50 -05:00
|
|
|
``int PyInitConfig_GetInt(PyInitConfig *config, const char *name, int64_t *value)``:
|
|
|
|
Get an integer configuration option.
|
|
|
|
|
|
|
|
* Set *\*value*, and return ``0`` on success.
|
|
|
|
* Set an error in *config* and return ``-1`` on error.
|
|
|
|
|
|
|
|
``int PyInitConfig_GetStr(PyInitConfig *config, const char *name, char **value)``:
|
|
|
|
Get a string configuration option as a null-terminated UTF-8
|
|
|
|
encoded string.
|
|
|
|
|
|
|
|
* Set *\*value*, and return ``0`` on success.
|
|
|
|
* Set an error in *config* and return ``-1`` on error.
|
|
|
|
|
|
|
|
On success, the string must be released with ``free(value)``.
|
|
|
|
|
|
|
|
``int PyInitConfig_GetStrList(PyInitConfig *config, const char *name, size_t *length, char ***items)``:
|
|
|
|
Get a string list configuration option as an array of
|
|
|
|
null-terminated UTF-8 encoded strings.
|
|
|
|
|
|
|
|
* Set *\*length* and *\*value*, and return ``0`` on success.
|
|
|
|
* Set an error in *config* and return ``-1`` on error.
|
|
|
|
|
|
|
|
On success, the string list must be released with
|
|
|
|
``PyInitConfig_FreeStrList(length, items)``.
|
|
|
|
|
|
|
|
``void PyInitConfig_FreeStrList(size_t length, char **items)``:
|
|
|
|
Free memory of a string list created by
|
|
|
|
``PyInitConfig_GetStrList()``.
|
|
|
|
|
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
Set Options
|
|
|
|
-----------
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
The configuration option *name* parameter must be a non-NULL
|
|
|
|
null-terminated UTF-8 encoded string.
|
|
|
|
|
|
|
|
Some configuration options have side effects on other options. This
|
|
|
|
logic is only implemented when ``Py_InitializeFromInitConfig()`` is
|
|
|
|
called, not by the "Set" functions below. For example, setting
|
2024-03-09 18:54:18 -05:00
|
|
|
``dev_mode`` to ``1`` does not set ``faulthandler`` to ``1``.
|
2024-03-08 09:35:01 -05:00
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
``int PyInitConfig_SetInt(PyInitConfig *config, const char *name, int64_t value)``:
|
|
|
|
Set an integer configuration option.
|
|
|
|
|
|
|
|
* Return ``0`` on success.
|
|
|
|
* Set an error in *config* and return ``-1`` on error.
|
|
|
|
|
|
|
|
``int PyInitConfig_SetStr(PyInitConfig *config, const char *name, const char *value)``:
|
2024-02-08 13:40:50 -05:00
|
|
|
Set a string configuration option from a null-terminated UTF-8
|
|
|
|
encoded string. The string is copied.
|
|
|
|
|
|
|
|
* Return ``0`` on success.
|
|
|
|
* Set an error in *config* and return ``-1`` on error.
|
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
``int PyInitConfig_SetStrList(PyInitConfig *config, const char *name, size_t length, char * const *items)``:
|
|
|
|
Set a string list configuration option from an array of
|
2024-02-08 13:40:50 -05:00
|
|
|
null-terminated UTF-8 encoded strings. The string list is copied.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-02-08 13:40:50 -05:00
|
|
|
* Return ``0`` on success.
|
|
|
|
* Set an error in *config* and return ``-1`` on error.
|
|
|
|
|
|
|
|
``int PyInitConfig_AddModule(PyInitConfig *config, const char *name, PyObject* (*initfunc)(void))``:
|
|
|
|
Add a built-in extension module to the table of built-in modules.
|
|
|
|
|
|
|
|
The new module can be imported by the name *name*, and uses the
|
|
|
|
function *initfunc* as the initialization function called on the
|
|
|
|
first attempted import.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
* Return ``0`` on success.
|
|
|
|
* Set an error in *config* and return ``-1`` on error.
|
|
|
|
|
2024-02-08 13:40:50 -05:00
|
|
|
If Python is initialized multiple times,
|
|
|
|
``PyInitConfig_AddModule()`` must be called at each Python
|
|
|
|
initialization.
|
|
|
|
|
|
|
|
Similar to the ``PyImport_AppendInittab()`` function.
|
|
|
|
|
|
|
|
|
|
|
|
Initialize Python
|
|
|
|
-----------------
|
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
``int Py_InitializeFromInitConfig(PyInitConfig *config)``:
|
|
|
|
Initialize Python from the initialization configuration.
|
|
|
|
|
|
|
|
* Return ``0`` on success.
|
|
|
|
* Set an error in *config* and return ``-1`` on error.
|
2024-03-14 08:47:23 -04:00
|
|
|
* Set an exit code in *config* and return ``-1`` if Python wants to
|
|
|
|
exit.
|
|
|
|
|
|
|
|
See ``PyInitConfig_GetExitcode()`` for the exitcode case.
|
2024-02-08 13:40:50 -05:00
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
Error Handling
|
2024-01-19 11:43:45 -05:00
|
|
|
--------------
|
|
|
|
|
|
|
|
``int PyInitConfig_GetError(PyInitConfig* config, const char **err_msg)``:
|
|
|
|
Get the *config* error message.
|
|
|
|
|
|
|
|
* Set *\*err_msg* and return ``1`` if an error is set.
|
|
|
|
* Set *\*err_msg* to ``NULL`` and return ``0`` otherwise.
|
|
|
|
|
|
|
|
An error message is an UTF-8 encoded string.
|
|
|
|
|
2024-03-14 08:47:23 -04:00
|
|
|
If *config* has an exit code, format the exit code as an error
|
|
|
|
message.
|
|
|
|
|
2024-02-08 13:40:50 -05:00
|
|
|
The error message remains valid until another ``PyInitConfig``
|
|
|
|
function is called with *config*. The caller doesn't have to free the
|
|
|
|
error message.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-03-14 08:47:23 -04:00
|
|
|
``int PyInitConfig_GetExitcode(PyInitConfig* config, int *exitcode)``:
|
|
|
|
Get the *config* exit code.
|
|
|
|
|
|
|
|
* Set *\*exitcode* and return ``1`` if Python wants to exit.
|
|
|
|
* Return ``0`` if *config* has no exit code set.
|
|
|
|
|
|
|
|
Only the ``Py_InitializeFromInitConfig()`` function can set an exit
|
|
|
|
code if the ``parse_argv`` option is non-zero. For example, an
|
|
|
|
isolated configuration cannot set an exit code by default, since
|
|
|
|
``parse_argv`` is zero by default.
|
|
|
|
|
|
|
|
An exit code can be set when parsing the command line failed (exit
|
|
|
|
code 2) or when a command line option asks to display the command
|
|
|
|
line help (exit code 0).
|
|
|
|
|
2024-02-08 13:40:50 -05:00
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
Get and Set the Runtime Configuration
|
2024-03-09 15:44:22 -05:00
|
|
|
-------------------------------------
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
The configuration option *name* parameter must be a non-NULL
|
|
|
|
null-terminated UTF-8 encoded string.
|
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
``PyObject* PyConfig_Get(const char *name)``:
|
2024-05-25 09:06:53 -04:00
|
|
|
Get the current runtime value of a configuration option as a Python
|
2024-03-09 19:23:55 -05:00
|
|
|
object.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
* Return a new reference on success.
|
|
|
|
* Set an exception and return ``NULL`` on error.
|
|
|
|
|
2024-03-09 18:54:18 -05:00
|
|
|
The object type depends on the option: see `Configuration Options`_
|
|
|
|
tables.
|
2024-02-08 13:40:50 -05:00
|
|
|
|
|
|
|
Other options are get from internal ``PyPreConfig`` and ``PyConfig`` structures.
|
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
The caller must hold the GIL. The function cannot be called before
|
|
|
|
Python initialization nor after Python finalization.
|
2024-02-08 13:40:50 -05:00
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
``int PyConfig_GetInt(const char *name, int *value)``:
|
|
|
|
Similar to ``PyConfig_Get()``, but get the value as an integer.
|
|
|
|
|
|
|
|
* Set ``*value`` and return ``0`` success.
|
|
|
|
* Set an exception and return ``-1`` on error.
|
|
|
|
|
2024-03-09 18:54:18 -05:00
|
|
|
``PyObject* PyConfig_Names(void)``:
|
2024-03-08 09:35:01 -05:00
|
|
|
Get all configuration option names as a ``frozenset``.
|
2024-02-08 13:40:50 -05:00
|
|
|
|
|
|
|
Set an exception and return ``NULL`` on error.
|
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
The caller must hold the GIL.
|
|
|
|
|
2024-03-09 15:44:22 -05:00
|
|
|
``PyObject* PyConfig_Set(const char *name, PyObject *value)``:
|
2024-03-09 19:23:55 -05:00
|
|
|
Set the current runtime value of a configuration option.
|
2024-02-08 13:40:50 -05:00
|
|
|
|
2024-03-09 15:44:22 -05:00
|
|
|
* Raise a ``ValueError`` if there is no option *name*.
|
|
|
|
* Raise a ``ValueError`` if *value* is an invalid value.
|
|
|
|
* Raise a ``ValueError`` if the option is read-only: cannot be set.
|
2024-03-09 19:23:55 -05:00
|
|
|
* Raise a ``TypeError`` if *value* has not the proper type.
|
2024-03-09 15:44:22 -05:00
|
|
|
|
2024-03-09 18:54:18 -05:00
|
|
|
`Read-only configuration options`_ cannot be set.
|
|
|
|
|
2024-03-09 15:44:22 -05:00
|
|
|
The caller must hold the GIL. The function cannot be called before
|
|
|
|
Python initialization nor after Python finalization.
|
|
|
|
|
|
|
|
|
2024-05-25 09:06:53 -04:00
|
|
|
Stability
|
|
|
|
---------
|
2024-03-08 09:35:01 -05:00
|
|
|
|
|
|
|
The behavior of options, the default option values, and the Python
|
|
|
|
behavior can change at each Python version: they are not "stable".
|
|
|
|
|
|
|
|
Moreover, configuration options can be added, deprecated and removed
|
|
|
|
following the usual :pep:`387` deprecation process.
|
|
|
|
|
|
|
|
|
2024-05-29 08:15:22 -04:00
|
|
|
Interaction with the PyPreConfig and PyConfig APIs
|
|
|
|
--------------------------------------------------
|
|
|
|
|
|
|
|
The lower level :pep:`587` ``PyPreConfig`` and ``PyConfig`` APIs remain
|
|
|
|
available and fully supported. As noted in the Abstract, they remain the
|
|
|
|
preferred approach for embedding use cases that are aiming to closely
|
|
|
|
emulate the behaviour of the full CPython CLI, rather than just making a
|
|
|
|
Python runtime available as part of a larger application.
|
|
|
|
|
|
|
|
The ``PyPreConfig`` APIs may be used in combination with the
|
|
|
|
initialization API in this PEP. In such cases, the read-only vs
|
|
|
|
read/write restrictions for preconfiguration settings apply to
|
|
|
|
``PyInitConfig_SetInt`` in addition to ``PyConfig_Set`` once the
|
|
|
|
interpreter has been preconfigured (specifically, only
|
|
|
|
``use_environment`` may be updated, attempting to update any of the
|
|
|
|
other preconfiguration variables will report an error).
|
|
|
|
|
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
Examples
|
|
|
|
========
|
|
|
|
|
|
|
|
Initialize Python
|
|
|
|
-----------------
|
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
Example initializing Python, set configuration options of different types,
|
|
|
|
return -1 on error:
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
.. code-block:: c
|
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
int init_python(void)
|
2024-01-19 11:43:45 -05:00
|
|
|
{
|
2024-05-29 08:15:22 -04:00
|
|
|
PyInitConfig *config = PyInitConfig_Create();
|
2024-01-19 11:43:45 -05:00
|
|
|
if (config == NULL) {
|
2024-03-08 09:35:01 -05:00
|
|
|
printf("PYTHON INIT ERROR: memory allocation failed\n");
|
|
|
|
return -1;
|
2024-01-19 11:43:45 -05:00
|
|
|
}
|
|
|
|
|
2024-02-08 13:40:50 -05:00
|
|
|
// Set an integer (dev mode)
|
2024-01-19 11:43:45 -05:00
|
|
|
if (PyInitConfig_SetInt(config, "dev_mode", 1) < 0) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2024-05-25 09:06:53 -04:00
|
|
|
// Set a list of UTF-8 strings (argv)
|
|
|
|
// Preinitialize implicitly Python to decode the bytes string.
|
|
|
|
char *argv[] = {"my_program", "-c", "pass"};
|
|
|
|
if (PyInitConfig_SetStrList(config, "argv",
|
2024-01-19 11:43:45 -05:00
|
|
|
Py_ARRAY_LENGTH(argv), argv) < 0) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2024-05-25 09:06:53 -04:00
|
|
|
// Set a UTF-8 string (program name)
|
|
|
|
if (PyInitConfig_SetStr(config, "program_name", L"my_program") < 0) {
|
2024-01-19 11:43:45 -05:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2024-05-25 09:06:53 -04:00
|
|
|
// Set a list of UTF-8 strings (xoptions).
|
2024-01-19 11:43:45 -05:00
|
|
|
char* xoptions[] = {"faulthandler"};
|
|
|
|
if (PyInitConfig_SetStrList(config, "xoptions",
|
|
|
|
Py_ARRAY_LENGTH(xoptions), xoptions) < 0) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize Python with the configuration
|
|
|
|
if (Py_InitializeFromInitConfig(config) < 0) {
|
2024-02-08 13:40:50 -05:00
|
|
|
goto error;
|
2024-01-19 11:43:45 -05:00
|
|
|
}
|
|
|
|
PyInitConfig_Free(config);
|
2024-03-08 09:35:01 -05:00
|
|
|
return 0;
|
2024-02-08 13:40:50 -05:00
|
|
|
|
|
|
|
error:
|
2024-03-08 09:35:01 -05:00
|
|
|
// Display the error message
|
|
|
|
const char *err_msg;
|
|
|
|
(void)PyInitConfig_GetError(config, &err_msg);
|
|
|
|
printf("PYTHON INIT ERROR: %s\n", err_msg);
|
|
|
|
PyInitConfig_Free(config);
|
|
|
|
|
|
|
|
return -1;
|
2024-01-19 11:43:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
Increase initialization bytes_warning option
|
|
|
|
--------------------------------------------
|
2024-01-19 11:43:45 -05:00
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
Example increasing the ``bytes_warning`` option of an initialization
|
|
|
|
configuration:
|
|
|
|
|
|
|
|
.. code-block:: c
|
|
|
|
|
|
|
|
int config_bytes_warning(PyInitConfig *config)
|
|
|
|
{
|
|
|
|
int bytes_warning;
|
|
|
|
if (PyInitConfig_GetInt(config, "bytes_warning", &bytes_warning)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
bytes_warning += 1;
|
|
|
|
if (PyInitConfig_SetInt(config, "bytes_warning", bytes_warning)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
Get the runtime verbose option
|
2024-03-08 09:35:01 -05:00
|
|
|
------------------------------
|
|
|
|
|
2024-03-09 19:23:55 -05:00
|
|
|
Example getting the current runtime value of the configuration option
|
2024-03-08 09:35:01 -05:00
|
|
|
``verbose``:
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
.. code-block:: c
|
|
|
|
|
|
|
|
int get_verbose(void)
|
|
|
|
{
|
|
|
|
int verbose;
|
|
|
|
if (PyConfig_GetInt("verbose", &verbose) < 0) {
|
|
|
|
// Silently ignore the error
|
|
|
|
PyErr_Clear();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return verbose;
|
|
|
|
}
|
|
|
|
|
2024-03-10 03:35:56 -04:00
|
|
|
On error, the function silently ignores the error and returns ``-1``. In
|
|
|
|
practice, getting the ``verbose`` option cannot fail, unless a future
|
|
|
|
Python version removes the option.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
|
|
|
|
Implementation
|
|
|
|
==============
|
|
|
|
|
|
|
|
* Issue: `No limited C API to customize Python initialization
|
|
|
|
<https://github.com/python/cpython/issues/107954>`_
|
|
|
|
* PR: `Add PyInitConfig C API
|
|
|
|
<https://github.com/python/cpython/pull/110176>`_
|
|
|
|
* PR: `Add PyConfig_Get() function
|
|
|
|
<https://github.com/python/cpython/pull/112609>`_
|
|
|
|
|
|
|
|
|
|
|
|
Backwards Compatibility
|
|
|
|
=======================
|
|
|
|
|
|
|
|
Changes are fully backward compatible. Only new APIs are added.
|
2024-02-08 13:40:50 -05:00
|
|
|
|
|
|
|
Existing API such as the ``PyConfig`` C API (PEP 587) are left
|
|
|
|
unchanged.
|
2024-01-19 11:43:45 -05:00
|
|
|
|
|
|
|
|
|
|
|
Rejected Ideas
|
|
|
|
==============
|
|
|
|
|
|
|
|
Configuration as text
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
It was proposed to provide the configuration as text to make the API
|
|
|
|
compatible with the stable ABI and to allow custom options.
|
|
|
|
|
|
|
|
Example::
|
|
|
|
|
|
|
|
# integer
|
|
|
|
bytes_warning = 2
|
|
|
|
|
|
|
|
# string
|
|
|
|
filesystem_encoding = "utf8" # comment
|
|
|
|
|
|
|
|
# list of strings
|
|
|
|
argv = ['python', '-c', 'code']
|
|
|
|
|
|
|
|
The API would take the configuration as a string, not as a file. Example
|
|
|
|
with a hypothetical ``PyInit_SetConfig()`` function:
|
|
|
|
|
|
|
|
.. code-block:: c
|
|
|
|
|
|
|
|
void stable_abi_init_demo(int set_path)
|
|
|
|
{
|
|
|
|
PyInit_SetConfig(
|
|
|
|
"isolated = 1\n"
|
|
|
|
"argv = ['python', '-c', 'code']\n"
|
|
|
|
"filesystem_encoding = 'utf-8'\n"
|
|
|
|
);
|
|
|
|
if (set_path) {
|
|
|
|
PyInit_SetConfig("pythonpath = '/my/path'");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
The example ignores error handling to make it easier to read.
|
|
|
|
|
|
|
|
The problem is that generating such configuration text requires adding
|
|
|
|
quotes to strings and to escape quotes in strings. Formatting an array
|
|
|
|
of strings becomes non-trivial.
|
|
|
|
|
|
|
|
Providing an API to format a string or an array of strings is not really
|
|
|
|
worth it, whereas Python can provide directly an API to set a
|
|
|
|
configuration option where the value is passed directly as a string or
|
|
|
|
an array of strings. It avoids giving special meaning to some
|
|
|
|
characters, such as newline characters, which would have to be escaped.
|
|
|
|
|
|
|
|
|
|
|
|
Refer to an option with an integer
|
|
|
|
----------------------------------
|
|
|
|
|
|
|
|
Using strings to refer to a configuration option requires comparing
|
|
|
|
strings which can be slower than comparing integers.
|
|
|
|
|
|
|
|
Use integers, similar to type "slots" such as ``Py_tp_doc``, to refer to
|
|
|
|
a configuration option. The ``const char *name`` parameter is replaced
|
|
|
|
with ``int option``.
|
|
|
|
|
|
|
|
Accepting custom options is more likely to cause conflicts when using
|
|
|
|
integers, since it's harder to maintain "namespaces" (ranges) for
|
|
|
|
integer options. Using strings, a simple prefix with a colon separator
|
|
|
|
can be used.
|
|
|
|
|
|
|
|
Integers also requires maintaining a list of integer constants and so
|
|
|
|
make the C API and the Python API larger.
|
|
|
|
|
|
|
|
Python 3.13 only has around 62 configuration options, and so performance
|
|
|
|
is not really a blocker issue. If better performance is needed later, a
|
|
|
|
hash table can be used to get an option by its name.
|
|
|
|
|
|
|
|
If getting a configuration option is used in hot code, the value can be
|
|
|
|
read once and cached. By the way, most configuration options cannot be
|
|
|
|
changed at runtime.
|
|
|
|
|
|
|
|
|
2024-03-09 02:58:39 -05:00
|
|
|
Multi-phase initialization (similar to PEP 432)
|
|
|
|
-----------------------------------------------
|
|
|
|
|
|
|
|
`Eric Snow expressed concerns <https://discuss.python.org/t/pep-741-python-configuration-c-api-second-version/45403/27>`_
|
|
|
|
that this proposal might reinforce with embedders the idea that
|
|
|
|
initialization is a single monolithic step. He argued that initialization
|
|
|
|
involves 5 distinct phases and even suggested that the API should
|
|
|
|
reflect this explicitly. Eric proposed that, at the very least, the
|
|
|
|
implementation of initialization should reflect the phases, in part
|
|
|
|
for improved code health. Overall, his explanation has some
|
|
|
|
similarities with :pep:`432` and :pep:`587`.
|
|
|
|
|
|
|
|
Another of Eric's key points relevant to this PEP was that, ideally,
|
|
|
|
the config passed to ``Py_InitializeFromConfig()`` should be complete
|
|
|
|
before that function is called, whereas currently initialization
|
|
|
|
actually modifies the config.
|
|
|
|
|
|
|
|
While Eric wasn't necessarily suggesting an alternative to PEP 741,
|
|
|
|
any proposal to add a granular initialization API around phases is
|
|
|
|
effectively the opposite of what this PEP is trying to accomplish.
|
|
|
|
Such API is more complicated, it requires adding new public structures
|
|
|
|
and new public functions. It makes the Python initialization more
|
|
|
|
complicated, rather than this PEP tries to unifiy existing APIs and make
|
|
|
|
them simpler (the opposite). Having multiple structures for similar
|
|
|
|
purpose can lead to duplicate members, similar issue than duplicated
|
|
|
|
members between existing ``PyPreConfig`` and ``PyConfig`` structures.
|
|
|
|
|
2024-03-08 09:35:01 -05:00
|
|
|
|
2024-05-29 08:15:22 -04:00
|
|
|
Locale encoding and wide strings
|
|
|
|
--------------------------------
|
|
|
|
|
|
|
|
Accepting strings encoded to the locale encoding and accepting wide
|
|
|
|
strings (``wchar_t*``) in the ``PyInitConfig`` API was deferred to keep
|
|
|
|
the ``PyInitConfig`` API simple and avoid the complexity of the Python
|
|
|
|
preinitialization. These features are also mostly needed when emulating
|
|
|
|
the full CPython CLI behaviour, and hence better served by the lower
|
|
|
|
level :pep:`587` API.
|
|
|
|
|
|
|
|
|
2024-01-19 12:00:45 -05:00
|
|
|
Discussions
|
|
|
|
===========
|
|
|
|
|
2024-02-08 19:00:51 -05:00
|
|
|
* `PEP 741: Python Configuration C API (second version)
|
|
|
|
<https://discuss.python.org/t/pep-741-python-configuration-c-api-second-version/45403>`_
|
|
|
|
(February 2024).
|
2024-01-19 12:00:45 -05:00
|
|
|
* `PEP 741: Python Configuration C API
|
|
|
|
<https://discuss.python.org/t/pep-741-python-configuration-c-api/43637>`_
|
2024-02-08 19:00:51 -05:00
|
|
|
(January 2024).
|
2024-01-19 12:00:45 -05:00
|
|
|
* `FR: Allow private runtime config to enable extending without breaking
|
|
|
|
the PyConfig ABI
|
|
|
|
<https://discuss.python.org/t/fr-allow-private-runtime-config-to-enable-extending-without-breaking-the-pyconfig-abi/18004>`__
|
|
|
|
(August 2022).
|
|
|
|
|
|
|
|
|
2024-01-19 11:43:45 -05:00
|
|
|
Copyright
|
|
|
|
=========
|
|
|
|
|
|
|
|
This document is placed in the public domain or under the
|
|
|
|
CC0-1.0-Universal license, whichever is more permissive.
|