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 33b7909

Browse filesBrowse files
vstinnerpicnixz
andauthored
gh-107954, PEP 741: Add PyConfig_Get()/Set() functions (#123472)
Add PyConfig_Get(), PyConfig_GetInt(), PyConfig_Set() and PyConfig_Names() functions to get and set the current runtime Python configuration. Add visibility and "sys spec" to config and preconfig specifications. _PyConfig_AsDict() now converts PyConfig.xoptions as a dictionary. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
1 parent db42934 commit 33b7909
Copy full SHA for 33b7909

File tree

Expand file treeCollapse file tree

19 files changed

+1466
-257
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

19 files changed

+1466
-257
lines changed
Open diff view settings
Collapse file

‎Doc/c-api/init_config.rst‎

Copy file name to clipboardExpand all lines: Doc/c-api/init_config.rst
+69Lines changed: 69 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1605,6 +1605,75 @@ customized Python always running in isolated mode using
16051605
:c:func:`Py_RunMain`.
16061606
16071607
1608+
Runtime Python configuration API
1609+
================================
1610+
1611+
The configuration option *name* parameter must be a non-NULL null-terminated
1612+
UTF-8 encoded string.
1613+
1614+
Some options are read from the :mod:`sys` attributes. For example, the option
1615+
``"argv"`` is read from :data:`sys.argv`.
1616+
1617+
1618+
.. c:function:: PyObject* PyConfig_Get(const char *name)
1619+
1620+
Get the current runtime value of a configuration option as a Python object.
1621+
1622+
* Return a new reference on success.
1623+
* Set an exception and return ``NULL`` on error.
1624+
1625+
The object type depends on the configuration option. It can be:
1626+
1627+
* ``bool``
1628+
* ``int``
1629+
* ``str``
1630+
* ``list[str]``
1631+
* ``dict[str, str]``
1632+
1633+
The caller must hold the GIL. The function cannot be called before
1634+
Python initialization nor after Python finalization.
1635+
1636+
.. versionadded:: 3.14
1637+
1638+
1639+
.. c:function:: int PyConfig_GetInt(const char *name, int *value)
1640+
1641+
Similar to :c:func:`PyConfig_Get`, but get the value as a C int.
1642+
1643+
* Return ``0`` on success.
1644+
* Set an exception and return ``-1`` on error.
1645+
1646+
.. versionadded:: 3.14
1647+
1648+
1649+
.. c:function:: PyObject* PyConfig_Names(void)
1650+
1651+
Get all configuration option names as a ``frozenset``.
1652+
1653+
* Return a new reference on success.
1654+
* Set an exception and return ``NULL`` on error.
1655+
1656+
The caller must hold the GIL. The function cannot be called before
1657+
Python initialization nor after Python finalization.
1658+
1659+
.. versionadded:: 3.14
1660+
1661+
1662+
.. c:function:: int PyConfig_Set(const char *name, PyObject *value)
1663+
1664+
Set the current runtime value of a configuration option.
1665+
1666+
* Raise a :exc:`ValueError` if there is no option *name*.
1667+
* Raise a :exc:`ValueError` if *value* is an invalid value.
1668+
* Raise a :exc:`ValueError` if the option is read-only (cannot be set).
1669+
* Raise a :exc:`TypeError` if *value* has not the proper type.
1670+
1671+
The caller must hold the GIL. The function cannot be called before
1672+
Python initialization nor after Python finalization.
1673+
1674+
.. versionadded:: 3.14
1675+
1676+
16081677
Py_GetArgcArgv()
16091678
================
16101679
Collapse file

‎Doc/whatsnew/3.14.rst‎

Copy file name to clipboardExpand all lines: Doc/whatsnew/3.14.rst
+9Lines changed: 9 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,15 @@ New Features
492492
* Add :c:func:`Py_HashBuffer` to compute and return the hash value of a buffer.
493493
(Contributed by Antoine Pitrou and Victor Stinner in :gh:`122854`.)
494494

495+
* Add functions to get and set the current runtime Python configuration:
496+
497+
* :c:func:`PyConfig_Get`
498+
* :c:func:`PyConfig_GetInt`
499+
* :c:func:`PyConfig_Set`
500+
* :c:func:`PyConfig_Names`
501+
502+
(Contributed by Victor Stinner in :gh:`107954`.)
503+
495504

496505
Porting to Python 3.14
497506
----------------------
Collapse file

‎Include/cpython/initconfig.h‎

Copy file name to clipboardExpand all lines: Include/cpython/initconfig.h
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,14 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,
260260
Py_ssize_t length, wchar_t **items);
261261

262262

263+
/* --- PyConfig_Get() ----------------------------------------- */
264+
265+
PyAPI_FUNC(PyObject*) PyConfig_Get(const char *name);
266+
PyAPI_FUNC(int) PyConfig_GetInt(const char *name, int *value);
267+
PyAPI_FUNC(PyObject*) PyConfig_Names(void);
268+
PyAPI_FUNC(int) PyConfig_Set(const char *name, PyObject *value);
269+
270+
263271
/* --- Helper functions --------------------------------------- */
264272

265273
/* Get the original command line arguments, before Python modified them.
Collapse file

‎Include/internal/pycore_initconfig.h‎

Copy file name to clipboardExpand all lines: Include/internal/pycore_initconfig.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ extern PyStatus _PyConfig_Write(const PyConfig *config,
181181
extern PyStatus _PyConfig_SetPyArgv(
182182
PyConfig *config,
183183
const _PyArgv *args);
184-
184+
extern PyObject* _PyConfig_CreateXOptionsDict(const PyConfig *config);
185185

186186
extern void _Py_DumpPathConfig(PyThreadState *tstate);
187187

Collapse file

‎Include/internal/pycore_sysmodule.h‎

Copy file name to clipboardExpand all lines: Include/internal/pycore_sysmodule.h
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ extern int _PySys_SetAttr(PyObject *, PyObject *);
2929
extern int _PySys_ClearAttrString(PyInterpreterState *interp,
3030
const char *name, int verbose);
3131

32+
extern int _PySys_SetFlagObj(Py_ssize_t pos, PyObject *new_value);
33+
extern int _PySys_SetIntMaxStrDigits(int maxdigits);
34+
3235
#ifdef __cplusplus
3336
}
3437
#endif
Collapse file

‎Lib/test/_test_embed_set_config.py‎

Copy file name to clipboardExpand all lines: Lib/test/_test_embed_set_config.py
+12-11Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ def test_set_invalid(self):
137137
'warnoptions',
138138
'module_search_paths',
139139
):
140-
value_tests.append((key, invalid_wstrlist))
140+
if key != 'xoptions':
141+
value_tests.append((key, invalid_wstrlist))
141142
type_tests.append((key, 123))
142143
type_tests.append((key, "abc"))
143144
type_tests.append((key, [123]))
@@ -160,14 +161,14 @@ def test_set_invalid(self):
160161
def test_flags(self):
161162
bool_options = set(BOOL_OPTIONS)
162163
for sys_attr, key, value in (
163-
("debug", "parser_debug", 1),
164-
("inspect", "inspect", 2),
165-
("interactive", "interactive", 3),
166-
("optimize", "optimization_level", 4),
167-
("verbose", "verbose", 1),
168-
("bytes_warning", "bytes_warning", 10),
169-
("quiet", "quiet", 11),
170-
("isolated", "isolated", 12),
164+
("debug", "parser_debug", 2),
165+
("inspect", "inspect", 3),
166+
("interactive", "interactive", 4),
167+
("optimize", "optimization_level", 5),
168+
("verbose", "verbose", 6),
169+
("bytes_warning", "bytes_warning", 7),
170+
("quiet", "quiet", 8),
171+
("isolated", "isolated", 9),
171172
):
172173
with self.subTest(sys=sys_attr, key=key, value=value):
173174
self.set_config(**{key: value, 'parse_argv': 0})
@@ -228,9 +229,9 @@ def test_options(self):
228229
self.check(warnoptions=[])
229230
self.check(warnoptions=["default", "ignore"])
230231

231-
self.set_config(xoptions=[])
232+
self.set_config(xoptions={})
232233
self.assertEqual(sys._xoptions, {})
233-
self.set_config(xoptions=["dev", "tracemalloc=5"])
234+
self.set_config(xoptions={"dev": True, "tracemalloc": "5"})
234235
self.assertEqual(sys._xoptions, {"dev": True, "tracemalloc": "5"})
235236

236237
def test_pathconfig(self):

0 commit comments

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