Skip to content

Commit ef9d547

Browse files
authored
gh-107954, PEP 741: Add PyInitConfig C API (#123502)
Add Doc/c-api/config.rst documentation.
1 parent 9e079c2 commit ef9d547

File tree

9 files changed

+976
-32
lines changed

9 files changed

+976
-32
lines changed

Doc/c-api/init.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
Initialization, Finalization, and Threads
88
*****************************************
99

10-
See also :ref:`Python Initialization Configuration <init-config>`.
10+
See also the :ref:`Python Initialization Configuration <init-config>`.
1111

1212
.. _pre-init-safe:
1313

Doc/c-api/init_config.rst

Lines changed: 235 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
Python Initialization Configuration
77
***********************************
88

9+
PyConfig C API
10+
==============
11+
912
.. versionadded:: 3.8
1013

1114
Python can be initialized with :c:func:`Py_InitializeFromConfig` and the
@@ -34,7 +37,7 @@ See also :ref:`Initialization, Finalization, and Threads <initialization>`.
3437

3538

3639
Example
37-
=======
40+
-------
3841

3942
Example of customized Python always running in isolated mode::
4043

@@ -73,7 +76,7 @@ Example of customized Python always running in isolated mode::
7376

7477

7578
PyWideStringList
76-
================
79+
----------------
7780

7881
.. c:type:: PyWideStringList
7982
@@ -116,7 +119,7 @@ PyWideStringList
116119
List items.
117120
118121
PyStatus
119-
========
122+
--------
120123
121124
.. c:type:: PyStatus
122125
@@ -210,7 +213,7 @@ Example::
210213
211214
212215
PyPreConfig
213-
===========
216+
-----------
214217
215218
.. c:type:: PyPreConfig
216219
@@ -360,7 +363,7 @@ PyPreConfig
360363
.. _c-preinit:
361364
362365
Preinitialize Python with PyPreConfig
363-
=====================================
366+
-------------------------------------
364367
365368
The preinitialization of Python:
366369
@@ -440,7 +443,7 @@ the :ref:`Python UTF-8 Mode <utf8-mode>`::
440443
441444
442445
PyConfig
443-
========
446+
--------
444447
445448
.. c:type:: PyConfig
446449
@@ -1349,7 +1352,7 @@ the :option:`-X` command line option.
13491352
13501353
13511354
Initialization with PyConfig
1352-
============================
1355+
----------------------------
13531356
13541357
Function to initialize Python:
13551358
@@ -1461,7 +1464,7 @@ initialization::
14611464
.. _init-isolated-conf:
14621465
14631466
Isolated Configuration
1464-
======================
1467+
----------------------
14651468
14661469
:c:func:`PyPreConfig_InitIsolatedConfig` and
14671470
:c:func:`PyConfig_InitIsolatedConfig` functions create a configuration to
@@ -1481,7 +1484,7 @@ to avoid computing the default path configuration.
14811484
.. _init-python-config:
14821485
14831486
Python Configuration
1484-
====================
1487+
--------------------
14851488
14861489
:c:func:`PyPreConfig_InitPythonConfig` and :c:func:`PyConfig_InitPythonConfig`
14871490
functions create a configuration to build a customized Python which behaves as
@@ -1499,7 +1502,7 @@ and :ref:`Python UTF-8 Mode <utf8-mode>`
14991502
.. _init-path-config:
15001503
15011504
Python Path Configuration
1502-
=========================
1505+
-------------------------
15031506
15041507
:c:type:`PyConfig` contains multiple fields for the path configuration:
15051508
@@ -1585,6 +1588,228 @@ The ``__PYVENV_LAUNCHER__`` environment variable is used to set
15851588
:c:member:`PyConfig.base_executable`.
15861589
15871590
1591+
PyInitConfig C API
1592+
==================
1593+
1594+
C API to configure the Python initialization (:pep:`741`).
1595+
1596+
.. versionadded:: 3.14
1597+
1598+
Create Config
1599+
-------------
1600+
1601+
.. c:struct:: PyInitConfig
1602+
1603+
Opaque structure to configure the Python initialization.
1604+
1605+
1606+
.. c:function:: PyInitConfig* PyInitConfig_Create(void)
1607+
1608+
Create a new initialization configuration using :ref:`Isolated Configuration
1609+
<init-isolated-conf>` default values.
1610+
1611+
It must be freed by :c:func:`PyInitConfig_Free`.
1612+
1613+
Return ``NULL`` on memory allocation failure.
1614+
1615+
1616+
.. c:function:: void PyInitConfig_Free(PyInitConfig *config)
1617+
1618+
Free memory of the initialization configuration *config*.
1619+
1620+
1621+
Error Handling
1622+
--------------
1623+
1624+
.. c:function:: int PyInitConfig_GetError(PyInitConfig* config, const char **err_msg)
1625+
1626+
Get the *config* error message.
1627+
1628+
* Set *\*err_msg* and return ``1`` if an error is set.
1629+
* Set *\*err_msg* to ``NULL`` and return ``0`` otherwise.
1630+
1631+
An error message is an UTF-8 encoded string.
1632+
1633+
If *config* has an exit code, format the exit code as an error
1634+
message.
1635+
1636+
The error message remains valid until another ``PyInitConfig``
1637+
function is called with *config*. The caller doesn't have to free the
1638+
error message.
1639+
1640+
1641+
.. c:function:: int PyInitConfig_GetExitCode(PyInitConfig* config, int *exitcode)
1642+
1643+
Get the *config* exit code.
1644+
1645+
* Set *\*exitcode* and return ``1`` if *config* has an exit code set.
1646+
* Return ``0`` if *config* has no exit code set.
1647+
1648+
Only the ``Py_InitializeFromInitConfig()`` function can set an exit
1649+
code if the ``parse_argv`` option is non-zero.
1650+
1651+
An exit code can be set when parsing the command line failed (exit
1652+
code ``2``) or when a command line option asks to display the command
1653+
line help (exit code ``0``).
1654+
1655+
1656+
Get Options
1657+
-----------
1658+
1659+
The configuration option *name* parameter must be a non-NULL
1660+
null-terminated UTF-8 encoded string.
1661+
1662+
.. c:function:: int PyInitConfig_HasOption(PyInitConfig *config, const char *name)
1663+
1664+
Test if the configuration has an option called *name*.
1665+
1666+
Return ``1`` if the option exists, or return ``0`` otherwise.
1667+
1668+
1669+
.. c:function:: int PyInitConfig_GetInt(PyInitConfig *config, const char *name, int64_t *value)
1670+
1671+
Get an integer configuration option.
1672+
1673+
* Set *\*value*, and return ``0`` on success.
1674+
* Set an error in *config* and return ``-1`` on error.
1675+
1676+
1677+
.. c:function:: int PyInitConfig_GetStr(PyInitConfig *config, const char *name, char **value)
1678+
1679+
Get a string configuration option as a null-terminated UTF-8
1680+
encoded string.
1681+
1682+
* Set *\*value*, and return ``0`` on success.
1683+
* Set an error in *config* and return ``-1`` on error.
1684+
1685+
*\*value* can be set to ``NULL`` if the option is an optional string and the
1686+
option is unset.
1687+
1688+
On success, the string must be released with ``free(value)`` if it's not
1689+
``NULL``.
1690+
1691+
1692+
.. c:function:: int PyInitConfig_GetStrList(PyInitConfig *config, const char *name, size_t *length, char ***items)
1693+
1694+
Get a string list configuration option as an array of
1695+
null-terminated UTF-8 encoded strings.
1696+
1697+
* Set *\*length* and *\*value*, and return ``0`` on success.
1698+
* Set an error in *config* and return ``-1`` on error.
1699+
1700+
On success, the string list must be released with
1701+
``PyInitConfig_FreeStrList(length, items)``.
1702+
1703+
1704+
.. c:function:: void PyInitConfig_FreeStrList(size_t length, char **items)
1705+
1706+
Free memory of a string list created by
1707+
``PyInitConfig_GetStrList()``.
1708+
1709+
1710+
Set Options
1711+
-----------
1712+
1713+
The configuration option *name* parameter must be a non-NULL null-terminated
1714+
UTF-8 encoded string.
1715+
1716+
Some configuration options have side effects on other options. This logic is
1717+
only implemented when ``Py_InitializeFromInitConfig()`` is called, not by the
1718+
"Set" functions below. For example, setting ``dev_mode`` to ``1`` does not set
1719+
``faulthandler`` to ``1``.
1720+
1721+
.. c:function:: int PyInitConfig_SetInt(PyInitConfig *config, const char *name, int64_t value)
1722+
1723+
Set an integer configuration option.
1724+
1725+
* Return ``0`` on success.
1726+
* Set an error in *config* and return ``-1`` on error.
1727+
1728+
1729+
.. c:function:: int PyInitConfig_SetStr(PyInitConfig *config, const char *name, const char *value)
1730+
1731+
Set a string configuration option from a null-terminated UTF-8
1732+
encoded string. The string is copied.
1733+
1734+
* Return ``0`` on success.
1735+
* Set an error in *config* and return ``-1`` on error.
1736+
1737+
1738+
.. c:function:: int PyInitConfig_SetStrList(PyInitConfig *config, const char *name, size_t length, char * const *items)
1739+
1740+
Set a string list configuration option from an array of
1741+
null-terminated UTF-8 encoded strings. The string list is copied.
1742+
1743+
* Return ``0`` on success.
1744+
* Set an error in *config* and return ``-1`` on error.
1745+
1746+
1747+
Initialize Python
1748+
-----------------
1749+
1750+
.. c:function:: int Py_InitializeFromInitConfig(PyInitConfig *config)
1751+
1752+
Initialize Python from the initialization configuration.
1753+
1754+
* Return ``0`` on success.
1755+
* Set an error in *config* and return ``-1`` on error.
1756+
* Set an exit code in *config* and return ``-1`` if Python wants to
1757+
exit.
1758+
1759+
See ``PyInitConfig_GetExitcode()`` for the exit code case.
1760+
1761+
1762+
Example
1763+
-------
1764+
1765+
Example initializing Python, set configuration options of various types,
1766+
return ``-1`` on error:
1767+
1768+
.. code-block:: c
1769+
1770+
int init_python(void)
1771+
{
1772+
PyInitConfig *config = PyInitConfig_Create();
1773+
if (config == NULL) {
1774+
printf("PYTHON INIT ERROR: memory allocation failed\n");
1775+
return -1;
1776+
}
1777+
1778+
// Set an integer (dev mode)
1779+
if (PyInitConfig_SetInt(config, "dev_mode", 1) < 0) {
1780+
goto error;
1781+
}
1782+
1783+
// Set a list of UTF-8 strings (argv)
1784+
char *argv[] = {"my_program", "-c", "pass"};
1785+
if (PyInitConfig_SetStrList(config, "argv",
1786+
Py_ARRAY_LENGTH(argv), argv) < 0) {
1787+
goto error;
1788+
}
1789+
1790+
// Set a UTF-8 string (program name)
1791+
if (PyInitConfig_SetStr(config, "program_name", L"my_program") < 0) {
1792+
goto error;
1793+
}
1794+
1795+
// Initialize Python with the configuration
1796+
if (Py_InitializeFromInitConfig(config) < 0) {
1797+
goto error;
1798+
}
1799+
PyInitConfig_Free(config);
1800+
return 0;
1801+
1802+
// Display the error message
1803+
const char *err_msg;
1804+
error:
1805+
(void)PyInitConfig_GetError(config, &err_msg);
1806+
printf("PYTHON INIT ERROR: %s\n", err_msg);
1807+
PyInitConfig_Free(config);
1808+
1809+
return -1;
1810+
}
1811+
1812+
15881813
Py_RunMain()
15891814
============
15901815

Doc/whatsnew/3.14.rst

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,8 @@ New Features
500500
* Add :c:func:`Py_HashBuffer` to compute and return the hash value of a buffer.
501501
(Contributed by Antoine Pitrou and Victor Stinner in :gh:`122854`.)
502502

503-
* Add functions to get and set the current runtime Python configuration:
503+
* Add functions to get and set the current runtime Python configuration
504+
(:pep:`741`):
504505

505506
* :c:func:`PyConfig_Get`
506507
* :c:func:`PyConfig_GetInt`
@@ -509,6 +510,24 @@ New Features
509510

510511
(Contributed by Victor Stinner in :gh:`107954`.)
511512

513+
* Add functions to configure the Python initialization (:pep:`741`):
514+
515+
* :c:func:`PyInitConfig_Create`
516+
* :c:func:`PyInitConfig_Free`
517+
* :c:func:`PyInitConfig_GetError`
518+
* :c:func:`PyInitConfig_GetExitCode`
519+
* :c:func:`PyInitConfig_HasOption`
520+
* :c:func:`PyInitConfig_GetInt`
521+
* :c:func:`PyInitConfig_GetStr`
522+
* :c:func:`PyInitConfig_GetStrList`
523+
* :c:func:`PyInitConfig_FreeStrList`
524+
* :c:func:`PyInitConfig_SetInt`
525+
* :c:func:`PyInitConfig_SetStr`
526+
* :c:func:`PyInitConfig_SetStrList`
527+
* :c:func:`Py_InitializeFromInitConfig`
528+
529+
(Contributed by Victor Stinner in :gh:`107954`.)
530+
512531

513532
Porting to Python 3.14
514533
----------------------

0 commit comments

Comments
 (0)