Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0eb3fd0

Browse filesBrowse files
committed
gh-107954, PEP 741: Add PyInitConfig C API
Add Doc/c-api/config.rst documentation.
1 parent f8a736b commit 0eb3fd0
Copy full SHA for 0eb3fd0

File tree

Expand file treeCollapse file tree

13 files changed

+952
-42
lines changed
Filter options
Expand file treeCollapse file tree

13 files changed

+952
-42
lines changed

‎Doc/c-api/config.rst

Copy file name to clipboard
+227Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
.. highlight:: c
2+
3+
.. _config-c-api:
4+
5+
********************
6+
Python Configuration
7+
********************
8+
9+
.. versionadded:: 3.14
10+
11+
C API to configure the Python initialization (:pep:`741`).
12+
13+
See also :ref:`Python Initialization Configuration <init-config>`.
14+
15+
16+
Initialize Python
17+
=================
18+
19+
Create Config
20+
-------------
21+
22+
.. c:struct:: PyInitConfig
23+
24+
Opaque structure to configure the Python initialization.
25+
26+
27+
.. c:function:: PyInitConfig* PyInitConfig_Create(void)
28+
29+
Create a new initialization configuration using :ref:`Isolated Configuration
30+
<init-isolated-conf>` default values.
31+
32+
It must be freed by :c:func:`PyInitConfig_Free`.
33+
34+
Return ``NULL`` on memory allocation failure.
35+
36+
37+
.. c:function:: void PyInitConfig_Free(PyInitConfig *config)
38+
39+
Free memory of the initialization configuration *config*.
40+
41+
42+
Get Options
43+
-----------
44+
45+
The configuration option *name* parameter must be a non-NULL
46+
null-terminated UTF-8 encoded string.
47+
48+
.. c:function:: int PyInitConfig_HasOption(PyInitConfig *config, const char *name)
49+
50+
Test if the configuration has an option called *name*.
51+
52+
Return ``1`` if the option exists, or return ``0`` otherwise.
53+
54+
55+
.. c:function:: int PyInitConfig_GetInt(PyInitConfig *config, const char *name, int64_t *value)
56+
57+
Get an integer configuration option.
58+
59+
* Set *\*value*, and return ``0`` on success.
60+
* Set an error in *config* and return ``-1`` on error.
61+
62+
63+
.. c:function:: int PyInitConfig_GetStr(PyInitConfig *config, const char *name, char **value)
64+
65+
Get a string configuration option as a null-terminated UTF-8
66+
encoded string.
67+
68+
* Set *\*value*, and return ``0`` on success.
69+
* Set an error in *config* and return ``-1`` on error.
70+
71+
On success, the string must be released with ``free(value)``.
72+
73+
74+
.. c:function:: int PyInitConfig_GetStrList(PyInitConfig *config, const char *name, size_t *length, char ***items)
75+
76+
Get a string list configuration option as an array of
77+
null-terminated UTF-8 encoded strings.
78+
79+
* Set *\*length* and *\*value*, and return ``0`` on success.
80+
* Set an error in *config* and return ``-1`` on error.
81+
82+
On success, the string list must be released with
83+
``PyInitConfig_FreeStrList(length, items)``.
84+
85+
86+
.. c:function:: void PyInitConfig_FreeStrList(size_t length, char **items)
87+
88+
Free memory of a string list created by
89+
``PyInitConfig_GetStrList()``.
90+
91+
92+
Set Options
93+
-----------
94+
95+
The configuration option *name* parameter must be a non-NULL null-terminated
96+
UTF-8 encoded string.
97+
98+
Some configuration options have side effects on other options. This logic is
99+
only implemented when ``Py_InitializeFromInitConfig()`` is called, not by the
100+
"Set" functions below. For example, setting ``dev_mode`` to ``1`` does not set
101+
``faulthandler`` to ``1``.
102+
103+
.. c:function:: int PyInitConfig_SetInt(PyInitConfig *config, const char *name, int64_t value)
104+
105+
Set an integer configuration option.
106+
107+
* Return ``0`` on success.
108+
* Set an error in *config* and return ``-1`` on error.
109+
110+
111+
.. c:function:: int PyInitConfig_SetStr(PyInitConfig *config, const char *name, const char *value)
112+
113+
Set a string configuration option from a null-terminated UTF-8
114+
encoded string. The string is copied.
115+
116+
* Return ``0`` on success.
117+
* Set an error in *config* and return ``-1`` on error.
118+
119+
120+
.. c:function:: int PyInitConfig_SetStrList(PyInitConfig *config, const char *name, size_t length, char * const *items)
121+
122+
Set a string list configuration option from an array of
123+
null-terminated UTF-8 encoded strings. The string list is copied.
124+
125+
* Return ``0`` on success.
126+
* Set an error in *config* and return ``-1`` on error.
127+
128+
129+
Initialize Python
130+
-----------------
131+
132+
.. c:function:: int Py_InitializeFromInitConfig(PyInitConfig *config)
133+
134+
Initialize Python from the initialization configuration.
135+
136+
* Return ``0`` on success.
137+
* Set an error in *config* and return ``-1`` on error.
138+
* Set an exit code in *config* and return ``-1`` if Python wants to
139+
exit.
140+
141+
See ``PyInitConfig_GetExitcode()`` for the exit code case.
142+
143+
144+
Error Handling
145+
--------------
146+
147+
.. c:function:: int PyInitConfig_GetError(PyInitConfig* config, const char **err_msg)
148+
149+
Get the *config* error message.
150+
151+
* Set *\*err_msg* and return ``1`` if an error is set.
152+
* Set *\*err_msg* to ``NULL`` and return ``0`` otherwise.
153+
154+
An error message is an UTF-8 encoded string.
155+
156+
If *config* has an exit code, format the exit code as an error
157+
message.
158+
159+
The error message remains valid until another ``PyInitConfig``
160+
function is called with *config*. The caller doesn't have to free the
161+
error message.
162+
163+
164+
.. c:function:: int PyInitConfig_GetExitCode(PyInitConfig* config, int *exitcode)
165+
166+
Get the *config* exit code.
167+
168+
* Set *\*exitcode* and return ``1`` if Python wants to exit.
169+
* Return ``0`` if *config* has no exit code set.
170+
171+
Only the ``Py_InitializeFromInitConfig()`` function can set an exit
172+
code if the ``parse_argv`` option is non-zero.
173+
174+
An exit code can be set when parsing the command line failed (exit
175+
code ``2``) or when a command line option asks to display the command
176+
line help (exit code ``0``).
177+
178+
179+
Example
180+
=======
181+
182+
Example initializing Python, set configuration options of various types,
183+
return ``-1`` on error:
184+
185+
.. code-block:: c
186+
187+
int init_python(void)
188+
{
189+
PyInitConfig *config = PyInitConfig_Create();
190+
if (config == NULL) {
191+
printf("PYTHON INIT ERROR: memory allocation failed\n");
192+
return -1;
193+
}
194+
195+
// Set an integer (dev mode)
196+
if (PyInitConfig_SetInt(config, "dev_mode", 1) < 0) {
197+
goto error;
198+
}
199+
200+
// Set a list of UTF-8 strings (argv)
201+
char *argv[] = {"my_program", "-c", "pass"};
202+
if (PyInitConfig_SetStrList(config, "argv",
203+
Py_ARRAY_LENGTH(argv), argv) < 0) {
204+
goto error;
205+
}
206+
207+
// Set a UTF-8 string (program name)
208+
if (PyInitConfig_SetStr(config, "program_name", L"my_program") < 0) {
209+
goto error;
210+
}
211+
212+
// Initialize Python with the configuration
213+
if (Py_InitializeFromInitConfig(config) < 0) {
214+
goto error;
215+
}
216+
PyInitConfig_Free(config);
217+
return 0;
218+
219+
error:
220+
// Display the error message
221+
const char *err_msg;
222+
(void)PyInitConfig_GetError(config, &err_msg);
223+
printf("PYTHON INIT ERROR: %s\n", err_msg);
224+
PyInitConfig_Free(config);
225+
226+
return -1;
227+
}

‎Doc/c-api/index.rst

Copy file name to clipboardExpand all lines: Doc/c-api/index.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ document the API functions in detail.
2222
concrete.rst
2323
init.rst
2424
init_config.rst
25+
config.rst
2526
memory.rst
2627
objimpl.rst
2728
apiabiversion.rst

‎Doc/c-api/init.rst

Copy file name to clipboardExpand all lines: Doc/c-api/init.rst
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
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>`
11+
and the :ref:`Python Configuration <config-c-api>`
1112

1213
.. _pre-init-safe:
1314

‎Doc/c-api/init_config.rst

Copy file name to clipboardExpand all lines: Doc/c-api/init_config.rst
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ There are two kinds of configuration:
2727
The :c:func:`Py_RunMain` function can be used to write a customized Python
2828
program.
2929

30-
See also :ref:`Initialization, Finalization, and Threads <initialization>`.
30+
See also :ref:`Initialization, Finalization, and Threads <initialization>`
31+
and the :ref:`Python Configuration <config-c-api>`.
3132

3233
.. seealso::
3334
:pep:`587` "Python Initialization Configuration".

‎Doc/whatsnew/3.14.rst

Copy file name to clipboardExpand all lines: Doc/whatsnew/3.14.rst
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,24 @@ New Features
485485

486486
(Contributed by Victor Stinner in :gh:`120389`.)
487487

488+
* Add functions to configure the Python initialization:
489+
490+
* :c:func:`PyInitConfig_Create`
491+
* :c:func:`PyInitConfig_Free`
492+
* :c:func:`PyInitConfig_HasOption`
493+
* :c:func:`PyInitConfig_GetInt`
494+
* :c:func:`PyInitConfig_GetStr`
495+
* :c:func:`PyInitConfig_GetStrList`
496+
* :c:func:`PyInitConfig_FreeStrList`
497+
* :c:func:`PyInitConfig_SetInt`
498+
* :c:func:`PyInitConfig_SetStr`
499+
* :c:func:`PyInitConfig_SetStrList`
500+
* :c:func:`Py_InitializeFromInitConfig`
501+
* :c:func:`PyInitConfig_GetError`
502+
* :c:func:`PyInitConfig_GetExitCode`
503+
504+
(Contributed by Victor Stinner in :gh:`107954`.)
505+
488506
Porting to Python 3.14
489507
----------------------
490508

‎Include/cpython/initconfig.h

Copy file name to clipboardExpand all lines: Include/cpython/initconfig.h
+60Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,66 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,
267267
See also PyConfig.orig_argv. */
268268
PyAPI_FUNC(void) Py_GetArgcArgv(int *argc, wchar_t ***argv);
269269

270+
271+
// --- PyInitConfig ---------------------------------------------------------
272+
273+
typedef struct PyInitConfig PyInitConfig;
274+
275+
// Create a new initialization configuration using the Isolated configuration
276+
// defaults.
277+
// It must be freed by PyInitConfig_Free().
278+
// Return NULL on memory allocation failure.
279+
PyAPI_FUNC(PyInitConfig*) PyInitConfig_Create(void);
280+
281+
// Free memory of a initialization configuration.
282+
PyAPI_FUNC(void) PyInitConfig_Free(PyInitConfig *config);
283+
284+
// Set an integer configuration option.
285+
// Return 0 on success, or return -1 on error.
286+
PyAPI_FUNC(int) PyInitConfig_SetInt(
287+
PyInitConfig *config,
288+
const char *name,
289+
int64_t value);
290+
291+
// Set a string configuration option from a bytes string.
292+
//
293+
// The bytes string is decoded by Py_DecodeLocale(). Preinitialize Python if
294+
// needed to ensure that encodings are properly configured.
295+
//
296+
// Return 0 on success, or return -1 on error.
297+
PyAPI_FUNC(int) PyInitConfig_SetStr(
298+
PyInitConfig *config,
299+
const char *name,
300+
const char *value);
301+
302+
// Set a string list configuration option from bytes strings.
303+
//
304+
// The bytes strings are decoded by Py_DecodeLocale(). Preinitialize Python if
305+
// needed to ensure that encodings are properly configured.
306+
//
307+
// Return 0 on success, or return -1 on error.
308+
PyAPI_FUNC(int) PyInitConfig_SetStrList(
309+
PyInitConfig *config,
310+
const char *name,
311+
size_t length,
312+
char * const *items);
313+
314+
// Initialize Python from the initialization configuration.
315+
// Return 0 on success.
316+
// Return -1 if Python wants to exit and on error
317+
PyAPI_FUNC(int) Py_InitializeFromInitConfig(PyInitConfig *config);
318+
319+
// Get the error message.
320+
// Set *err_msg and return 1 if an error is set.
321+
// Set *err_msg to NULL and return 0 otherwise.
322+
PyAPI_FUNC(int) PyInitConfig_GetError(PyInitConfig* config, const char **err_msg);
323+
324+
// Get the exit code.
325+
// Set '*exitcode' and return 1 if an exit code is set.
326+
// Return 0 otherwise.
327+
PyAPI_FUNC(int) PyInitConfig_GetExitCode(PyInitConfig* config, int *exitcode);
328+
329+
270330
#ifdef __cplusplus
271331
}
272332
#endif

‎Include/internal/pycore_initconfig.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_initconfig.h
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ extern int _PyWideStringList_Copy(PyWideStringList *list,
6262
extern PyStatus _PyWideStringList_Extend(PyWideStringList *list,
6363
const PyWideStringList *list2);
6464
extern PyObject* _PyWideStringList_AsList(const PyWideStringList *list);
65+
extern PyStatus _PyWideStringList_FromBytes(
66+
PyWideStringList *list,
67+
Py_ssize_t length,
68+
char * const *items);
6569

6670

6771
/* --- _PyArgv ---------------------------------------------------- */

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.